gc
git 커밋/체크아웃을 구별할 수 있는 스마트 별칭을 만들고 있습니다 .
인수 없이 호출하거나 , 인수를 사용하여 호출하면 gc
git commit이 실행됩니다. 그렇지 않으면 git checkout을 실행하십시오(추가 매개변수가 있는 플래그가 있는 경우). gc의 다른 변형이 호출되면 예상치 못한 작업을 수행하기보다는 오류를 발생시키기를 원합니다.-a
-m
b
이것은 지금까지 나의 쉘 기능입니다.
gc() {
args=$@
commit=false
checkout=false
# Check flags
while getopts ":am:b" opt; do
case $opt in
a|m)
commit=true
;;
b)
checkout=true
;;
\?)
echo "Unknown flags passed."
return 1
;;
esac
done
shift "$((OPTIND-1))"
# Check number of arguments
if [[ "$#" == 0 ]]; then
commit=true
elif [[ "$#" == 1 ]]; then
checkout=true
else
echo "Too many arguments"
return 1
fi
# Finally run respective command
if [[ $commit == true && $checkout == true ]]; then
echo "Unable to ascertain which operation you would like to perform."
return 1
elif [[ $commit == true ]]; then
git commit "$args"
elif [[ $checkout == true ]]; then
git checkout "$args"
else
echo "Undefined behavior"
return 1
fi
}
그러나 이것은 제대로 작동하지 않습니다. 몇 가지 실험을 통해 다른 변수에 할당하는 것이 근본 원인이라는 것을 알았지 $@
만 왜 그리고 정확히 무엇이 잘못되었는지 이해할 수 없습니다.
또한 쉘 함수를 작성하는 것은 이번이 처음이므로 제가 저지른 실수를 지적해 주시기 바랍니다.
답변1
$@
배열인 경우 배열에 할당합니다.
args=("$@")
그런 다음 배열로 사용하십시오.
elif [[ $commit == true ]]; then
git commit "${args[@]}"
elif [[ $checkout == true ]]; then
git checkout "${args[@]}"
else
현재 코드에서 일어나는 일은 모든 개별 매개변수가 단일 문자열로 저장된다는 것입니다. 따라서 전화를 하면:
bc -a "foo bar"
다음과 같이 할당됩니다 args
.
args='-a foo bar'
그런 다음 실행하는 대신 다음을 수행하십시오.
git commit -a "foo bar"
당신은 다음을 얻습니다:
git commit '-a foo bar'
기타 참고사항:
"$args[@]"
zsh에서는 or"${(@)args}"
대신 사용할 수도 있지만"${args[@]}"
bash/ksh에서는 사용할 수 없습니다."$args"
yash에서 작동하지만 ksh/bash에서는zsh
(연결된 요소의 첫 번째 문자) 및 ksh/bash와 동일합니다. zsh에서는 이것이 작동하지만 빈 요소가 있는 경우 제거됩니다."$args[*]"
$IFS
"${args[0]}"
$args
getopts
함수에서 사용할 때는 미리 무언가를 추가해야 합니다local OPTIND OPTARG
(특히OPTIND
또는 적어도 초기화/설정 해제). zsh는OPTIND
다른 쉘을 에뮬레이션하지 않을 때 이 작업을 자동으로 수행하지만 ksh/bash/yash는 그렇지 않습니다. 함수 내에서 사용하는 다른 변수도 지역 변수로 설정해야 합니다.- 오류는 stderr(fd 2)로 전송되어야 합니다
echo>&2 Too many arguments
.
답변2
다른 답변은 POSIX가 아니므로 여기에 대안이 있습니다. 일시적으로 위치 매개변수를 분쇄하려면 다음을 수행하십시오.
s1=$(printf '%s\n' "$@")
그런 다음 복구할 준비가 되면 다음을 수행하세요.
IFS='
'
set -- $s1
이는 인수에 개행 문자가 포함되어 있지 않다고 가정합니다. 이렇게 하면 다른 구분 기호를 사용해야 합니다.
참고 사항: 마지막 줄에는 따옴표가 없는 변수가 포함되어 있습니다. 이는 인용되지 않은 변수가 허용되는 몇 안 되는 경우(제 생각에는 유일한 경우) 중 하나입니다. 사용자가 명시적으로 설정한 경우입니다 IFS
. 사용자는 본질적으로 "예, 제가 하고 있는 일을 알고 있습니다. 계속하십시오"라고 말합니다. .