스크립트의 변수에 시간 초과 명령 할당

스크립트의 변수에 시간 초과 명령 할당

nvlc가 실행되는 시간을 설정하려고 합니다. 실제로 하나의 Case 문에 여러 개의 nvlc 명령이 있으므로 재생할 스트림을 선택할 수 있습니다. 스크립트를 gitlab 스니펫으로 게시했습니다.여기.

기간을 설정하고 싶거나 $duration이 설정되지 않았거나 0으로 설정된 경우 "nvlc"(초는 s, 분은 m) 앞에 "timeout (duration) s"가 추가되지 않습니다.

read -p "What duration in MINUTES do you want the recording to run for? :  " duration
if [ -z ${duration+x} -o $duration = 0 ]; then t=""; else t='timeout '"$duration"'m'; fi

나중에(라인 47 및 기타) nvlc는 다음과 같이 호출됩니다.

"$t" nvlc stream-url

따라서 기간이 설정되지 않거나 0으로 설정된 경우 "$t"는 공백일 뿐이지만 기간에 대한 값이 설정된 경우 기간 변수는 nvlc 명령에서 해석됩니다. 예: timeout 60m nvlc stream -url

다양한 오류가 발생합니다. t='timeout '"$duration"''s'를 사용할 때 오류는 다음과 같습니다. 47행: 시간 초과 5초: 명령을 찾을 수 없습니다.

t='timeout $durations'를 사용할 때 오류는 다음과 같습니다. Line 47: timeout $durations: 명령을 찾을 수 없습니다.

내가 어디에서 잘못되고 있는지 지적해 주실 수 있나요?

답변1

여기에는 몇 가지 문제가 있습니다. 첫 번째는 $t큰따옴표로 확장하는 것입니다.

"$t" nvlc stream-url

변수 참조를 큰따옴표로 묶으면 실수로 인한 토큰화 및/또는 와일드카드 확장을 방지할 수 있으므로 거의 항상 좋은 생각이지만 이 경우에는필요분사. t로 설정된 경우 큰따옴표를 사용하면 쉘이 전체 문자열을 (명령 이름) 및 (해당 인수) timeout 5s로 분할하지 않고 명령 이름으로 처리합니다 . 또한 빈 문자열로 설정하면 명령에서 사라질 뿐만 아니라 실제로는 빈 문자열을 명령 이름으로 실행하려고 시도합니다! 이 문제를 해결하려면 큰따옴표를 제거하면 됩니다.timeout5st

$t nvlc stream-url

(명령이 더 복잡한 경우 일반 변수 대신 배열을 사용해야 할 수도 있습니다.BashFAQ #50: 명령을 변수에 넣으려고 하는데 복잡한 경우에는 항상 실패합니다!)

두 번째 문제는 조건식입니다 [ -z ${duration+x} -o $duration = 0 ]. duration인용되어 있어서아니요여기에는 큰따옴표로 묶여 있습니다.하다duration빈 문자열로 설정하면 사라지므로 전체 내용이 로 확장되므로 [ -z x -o = 0 ]유효하지 않습니다. 여기 당신필요큰따옴표로 묶으십시오. 또한 +x첫 번째 테스트에서 이를 제거하거나 다음으로 바꾸십시오 :+x. +x변수가 설정된 경우(빈 문자열로 설정된 경우에도) 옵션은 이를 "x"로 확장하지만 단지 read2개 이므로언제나"x"로 확장합니다. +x적절한 큰따옴표를 제거하고 추가하기만 하면 됩니다.

if [ -z "${duration}" -o "$duration" = 0 ]; then ...

마지막으로 인용문이 t='timeout '"$duration"'m'이상합니다. 틀린 것이 아니라 지나치게 복잡할 뿐입니다. 변수가 아닌 부분을 작은 따옴표로 묶는 것은 중복되며 전체 내용을 작은 따옴표로 묶으면 변수가 확장되지 않습니다. 전체 내용을 큰따옴표로 묶는 것이 더 간단하고 명확합니다.

t="timeout ${duration}m"

(중괄호가 필요하므로 "m"(또는 일부 버전에서는 "s")은 변수 이름의 일부로 간주되지 않습니다.)

관련 정보