다음 쉘 함수를 정의했습니다.
success() {
printf "[\033[32mSUCCESS\033[0m]\n"
}
failure() {
printf "[\033[31mFAILURE\033[0m]\n"
}
try() {
result=$($* 2>&1)
if [ $? -ne 0 ]; then
failure
echo $result
exit 1
fi
success
}
이를 통해 모든 명령을 자동으로 실행하고, 모든 출력을 캡처하고, 표시 SUCCESS
하거나 FAILURE
메시지를 표시할 수 있습니다. 명령 출력은 명령이 실패한 경우에만 디버깅 목적으로 표시됩니다.
try rm -r $tmp
그러나 나는 그것이 단일 명령으로 제한되어 있고 다른 명령으로 파이프된 명령에 대해 비참하게 실패한다는 것을 깨달았습니다 |
.
try git archive --format=tar HEAD | tar xf - -C $tmp
try
명령에 대해서만 실행되므로 의 git
출력은 의 출력이 아닌 try
으로 파이프 됩니다 .tar
git
git ... | tar ...
두 명령을 단일 인수로 전달할 수 있습니까 ?try
, 둘 다의 출력을 캡처하고 둘 다 반환 git
되는지 확인하십시오 .tar
0
내 목표를 달성하기 위해 다른 고려 사항이 있습니까?
답변1
git … | tar …
파이프(두 개의 개별 명령이 아닌 두 개의 하위 명령을 포함하는 단일 명령)를 함수에 직접 인수로 전달 하려면 명령이 포함된 문자열을 만들고 eval
함수에 내장된 함수를 사용해야 합니다. 이 문자열을 쉘 명령으로 실행합니다.
올바른 인용에 주의하세요. 인수의 경우 포함 스크립트와 동일한 변수를 사용하여 미니 쉘 스크립트인 문자열을 작성합니다. 특히 변수에 파일 이름이 포함된 경우( tmp
여기서와 같이) 변수 값이 아닌 변수 확장을 전달해야 합니다. 파일 이름은 쉘 조각이 아니므로 '…"$tmp"…'
대신 확장이 필요하기 때문입니다 "…$tmp…"
. 평가할 때 eval
확장된 문자열이 아닌 정확한 문자열을 전달해야 합니다 . 특히, $*
거의 항상 잘못된 내용을 읽습니다.공백이나 기타 특수 문자 때문에 쉘 스크립트가 멈추는 이유는 무엇입니까?
try () {
result=$(eval "$1" 2>&1)
if [ $? -ne 0 ]; then
failure
echo $result
exit 1
fi
success
}
try 'git archive --format=tar HEAD | tar xf - -C "$tmp"'
또 다른 접근 방식은 복합 명령을 함수에 넣는 것입니다. 다시 한 번 정확하게 인용하십시오. "$@"
함수의 매개변수를 간단한 명령(별명, 함수, 매개변수가 있는 내장 또는 외부 명령)으로 평가하는 데 사용됩니다 .
try () {
result=$(eval "$1" 2>&1)
if [ $? -ne 0 ]; then
failure
echo $result
exit 1
fi
success
}
archive_to_directory () {
git archive --format=tar HEAD | tar xf - -C "$1"'
}
try archive_to_directory "$tmp"
파이프의 상태는 오른쪽의 상태이며 왼쪽의 상태는 무시됩니다. bash에서는(sh에서는 제외) 다음을 통해 파이프라인의 모든 명령 상태에 액세스할 수 있습니다.PIPESTATUS
바꾸다.
try () {
result=$(eval "$1" 2>&1)
if [ $? -ne 0 ]; then
failure
echo $result
exit 1
fi
success
}
archive_to_directory () {
git archive --format=tar HEAD | tar xf - -C "$1"'
[[ -n ${PIPESTATUS[*]//[0 ]/} ]]
}
try archive_to_directory "$tmp"
답변2
명령줄에 따옴표를 추가해야 합니다. 이는 불가피합니다.
try "git archive --format=tar HEAD | tar xf - -C $tmp"
그런 다음 함수에서 셸 메타 문자(예: |
)는 변수에 저장될 때 특별하지 않으므로 다음이 필요합니다.eval
try() {
if result=$(eval "$*" 2>&1); then
success
else
failure
echo $result
exit 1
fi
}
아직은 이 부분이 제대로 이해되지 않았다는 느낌이 듭니다. 누군가가 나를 고칠 수 있기를 바랍니다.