에는 bashrc
3개의 변수를 사용하는 경고 함수가 있습니다.
a () {
local $1="${1:-3600}"
local $2="${2:-paa}"
local $3="${3:-alarm}"
sleep "$1" && $2 && $3
}
alias pah='pactl set-card-profile 0 output:hdmi-stereo'
alias paa='pactl set-card-profile 0 output:analog-stereo'
alias alarm='vlc ~/alarm.mp3'
명령줄에서 다음 명령은 내 별칭을 정상적으로 실행합니다.
sleep 3600 && paa && alarm
그러나 위에 표시된 함수의 이 부분을 만들려고 하면 다음 오류가 발생합니다.
bash: pah: command not found
게다가:$1, $2, $3변수의 기본값은 다음과 같습니다.3600,파아, 그리고경보.
또한 $1과 $2의 기본값을 허용하면서 $3 입력으로 이 함수를 호출하는 방법에 대해서도 혼란스럽습니다.
즉
a null null alarm2
재게시 참고 사항: 이 질문을 Stack Overflow에 게시했지만 이 질문이 Unix & Linux Stack Exchange에 속할 수도 있다는 것을 깨달았습니다.
답변1
실행에서 이 출력을 얻는 방법을 이해할 수 없습니다 a
. 출력의 다른 버전을 게시했습니까? 하지만 어쨌든 코드에 어떤 문제가 있는지 알 수 있습니다.
첫 번째 문제는 local $1=…
당신이 생각하는 대로 이루어지지 않는다는 것이다. 첫 번째 인수라는 변수를 설정하지만 첫 번째 인수를 설정하지는 않습니다. 예를 들어 함수가 호출되면 a foo
첫 번째 줄에서는 지역 변수를 foo
값으로 설정합니다 foo
. a
매개변수 없이 호출 하면 다음과 같은 결과가 나타납니다.
bash: local: `=3600': not a valid identifier
(및 더 많은 오류) 의 왼쪽 =
은 빈 문자열이고 해당 빈 문자열은 변수의 유효한 이름이 아니기 때문입니다.
번호가 매겨진 매개변수를 설정하기 위해 할당 구문을 사용할 수 없습니다. local 1=…
이 방법도 작동하지 않습니다. set
번호가 매겨진 모든 매개변수를 한 번에 설정하려면 변수의 이름을 지정하거나 내장 함수를 사용해야 합니다 .
a () {
local delay="${1:-3600}"
local first_command_to_split_and_glob="${2:-paa}"
local second_command_to_split_and_glob="${3:-alarm}"
sleep "$delay" && $first_command_to_split_and_glob && $second_command_to_split_and_glob
}
두 번째 문제는 별칭이 명령 시작 부분에 명시적으로 나타나는 경우에만 확장된다는 것입니다. 다른 확장(예: 변수 값 가져오기)의 결과로 확장되지 않습니다.
호출의 또 다른 문제점은 $first_command_to_split_and_glob
간단한 경우에만 작동한다는 것입니다. 공백으로 변수 값(즉, 함수에 전달된 인수)을 분할한 다음 각 부분을 와일드카드 패턴으로 해석하고 패턴이 하나 이상의 파일 이름과 일치하면 확장됩니다. 예를 들어, , 및 이라는 a 2 'cat "file name with spaces"'
파일의 내용을 표시해 보십시오. 따옴표 밖의 변수 확장은 "split+glob" 작업을 적용합니다. 즉, 변수 값을 생성하지도 않고 해당 값을 평가하지도 않지만 그 사이에 있는 항목은 거의 유용하지 않습니다. 바라보다"file
name
with
spaces"
공백이나 기타 특수 문자 때문에 쉘 스크립트가 멈추는 이유는 무엇입니까?자세한 내용은.
두 문제를 모두 해결하려면 eval
문자열에 사용하세요. 분할+글로브를 방지하려면 "$first_command"
및 주위에 큰따옴표를 사용하십시오 ."$second_command"
a () {
local delay="${1:-3600}"
local first_command="${2:-paa}"
local second_command="${3:-alarm}"
sleep "$delay" && eval "$first_command" && eval "$second_command"
}
마지막으로 빈 매개변수를 전달하려면 따옴표를 사용하여 빈 문자열을 구분하세요. 예를 들어:
a '' pah
3600초 동안 기다린 후 를 실행 pah
하고 를 실행합니다 alarm
.