명령이 실패하지 않은 경우에만 a
명령 결과의 첫 번째 단어를 내 변수에 할당하고 싶습니다. func <some_arg>
실패하면 문서화해야 합니다.
지금까지 내가 한 일은 다음과 같습니다.
func() {
if [[ $1 -eq 1 ]]
then
echo 'hello world'
return 0
fi
echo 'Something wrong has happened!' >> path/to/dev.log
return 2
}
a=$(func 1)
r=$?
if [[ $r -eq 0 ]]
then
a=$(awk '{ print $1 }' <<<"$a")
fi
이것은 확실히 작동하지만 변수를 두 번 할당하는 것을 좋아하지 않습니다 a
.
나는 이것을 시도했습니다 :
a=$(func 2 | awk '{ print $1 }') || echo 'Something wrong has happened!' >> path/to/dev.log
하지만 아무것도 기록하지 않습니다
더 좋은 방법이 있나요?
답변1
set -o pipefail
다음을 사용하여 파이프라인의 이전 부분에서 오류를 얻을 수 있습니다 .
파이프의 반환 상태는 마지막 명령의 종료 상태입니다.파이프 고장옵션이 활성화되었습니다. 만약에파이프 고장활성화되면 파이프의 반환 상태는 0이 아닌 상태로 종료된 마지막(가장 오른쪽) 명령의 값이거나 모든 명령이 성공적으로 종료된 경우 0입니다.
$ foo() { [[ "$1" = 1 ]] || return 1; echo "hello world"; }
$ a=$(set -o pipefail; foo 2 | awk '{print $1}' || echo "fail..." >&2)
fail...
하지만 실제로는 왜 두 번 할당하는 것이 문제가 되는지 이해가 되지 않습니다. 기본적으로 명령이 성공하면 얻은 값을 수정하고 명령이 실패하면 무시합니다.
또는 해당 논리를 약간 압축할 수 있습니다.
if a=$(foo 1); then
a=${a%% *};
echo "first word of a is '$a'";
# do some work with $a...
else
echo "error..." >&2;
fi
인쇄
first word of a is 'hello'
답변2
셸에는 문자열의 첫 번째 단어를 구문 분석하는 몇 가지 기본 메서드가 있습니다.
접미사로 다듬기 -
${a%% *}
위치 인수에 할당 -
set -- ${a}
결과는 에 있습니다$1
. 를 사용하여 이를 단순화할 수 있습니다set -- $(func 1)
.bash
(만) 배열 요소로 나누기 -a=( $(func 1) )
- 결과는 에 있습니다${a[0]}
.
답변3
a
코드의 한 가지 문제는 함수가 func
0이 아닌 결과를 반환하더라도 충돌이 발생한다는 것입니다.
대신에:
#!/bin/sh
func () {
if [ "$1" -eq 1 ]; then
echo 'some sort of logging stuff' >>logfile
return 1
fi
echo 'hello world'
}
a="a string"
if b=$( func 0 ); then
a=${b%% *}
fi
printf '1: a = "%s"\n' "$a"
a="a string"
if b=$( func 1 ); then
a=${b%% *}
fi
printf '2: a = "%s"\n' "$a"
이것을 실행하면
1: a = "hello"
2: a = "a string"
보시다시피 두 번째 경우에는 a
해당 값이 유지됩니다.