![Bash의 조건이 다중 문인 경우](https://linux55.com/image/4038/Bash%EC%9D%98%20%EC%A1%B0%EA%B1%B4%EC%9D%B4%20%EB%8B%A4%EC%A4%91%20%EB%AC%B8%EC%9D%B8%20%EA%B2%BD%EC%9A%B0.png)
다음과 같은 if 조건에서 여러 명령문을 실행하고 싶습니다.
[[ -e cli.tar.gz ]] && `tar -xvf cli.tar.gz -C ~/` ||
echo "cli.tar.gz can not be found. Exiting" >&2 && exit 1
cli.tar.gz를 찾아서 타르하면 출구 1에 도달하는데, 이는 내가 달성하려는 것과 정반대이므로 다음과 같이 OR 다음 부분 주위에 괄호를 추가했습니다.
[[ -e cli.tar.gz ]] && tar -xvf cli.tar.gz -C ~/ ||
{ echo "cli.tar.gz can not be found. Exiting" >&2; exit 1; }
함수 끝에 Unexpected token "}" 오류가 발생합니다(이 줄은 함수의 일부입니다).
형식이 잘 지정된 if 조건을 작성하여 문제를 해결했습니다.
if [[ -e cli.tar.gz ]]
then
if [[ ! `tar -xvf cli.tar.gz -C ${UDM_REMOTE}` ]]
then
echo "cli.tar.gz can not be found. Exiting" >&2; exit 1;
fi
fi
하지만 처음에 달성하려고 했던 것처럼 한 줄에 중첩된 if 조건을 수행하는 솔루션은 무엇입니까?
업데이트 1 @uwe와 @goldilocks의 답변 덕분에 아래 설명을 업데이트했고 이제 작동합니다.
[[ ! -e cli.tar.gz ]] && ! `tar -xvf cli.tar.gz -C ~/` && \
echo "cli.tar.gz can not be found (or tar failed). Exiting" >&2 && exit 1
답변1
if [[ ! -e cli.tar.gz ]] || ! tar -xvf cli.tar.gz -C ~/ ; then
echo "cli.tar.gz can not be found (or tar failed). Exiting" >&2 && exit 1
fi
또는 완전히 피하고 싶다면 다음과 같이 하세요 if
.
( [[ ! -e cli.tar.gz ]] || ! tar -xvf cli.tar.gz -C ~/ ) && { echo "cli.tar.gz can not be found (or tar failed). Exiting" >&2 ; exit 1 ; }
답변2
if [[ -e cli.tar.gz && ( $(tar -xvf cli.tar.gz -C ~/) && $? != 0 ) ]]; then
echo "cli.tar.gz can not be found (or tar failed). Exiting" >&2 && exit 1
fi
답변3
&&
사용하는 방식은 ||
조건이 아닌 목록입니다.
Lists
A list is a sequence of one or more pipelines separated by one of the
operators ;, &, &&, or ⎪⎪, and optionally terminated by one of ;, &, or
<newline>.
Of these list operators, && and ⎪⎪ have equal precedence, followed by ;
and &, which have equal precedence.
A sequence of one or more newlines may appear in a list instead of a
semicolon to delimit commands.
If a command is terminated by the control operator &, the shell executes
the command in the background in a subshell. The shell does not wait for
the command to finish, and the return status is 0. Commands
separated by a ; are executed sequentially; the shell waits for each
command to terminate in turn. The return status is the exit status of
the last command executed.
AND and OR lists are sequences of one of more pipelines separated by the
&& and ⎪⎪ control operators, respectively. AND and OR lists are executed
with left associativity. An AND list has the form
command1 && command2
command2 is executed if, and only if, command1 returns an exit status of
zero.
An OR list has the form
command1 ⎪⎪ command2
command2 is executed if and only if command1 returns a non-zero exit
status. The return status of AND and OR lists is the exit status of the
last command executed in the list.
"SO Q&A"라는 제목의 질문을 보면 다음과 같습니다.BASH의 간단한 논리 연산자, @Gilles의 답변은 Bash에서 if/then 블록을 처리하는 방법을 설명하는 데 있어 최대한 간결합니다.
리팩토링 실행 #1
따라서 귀하의 진술을 재구성한 버전은 다음과 같습니다 if/then
.
[[ -e cli.tar.gz && `tar -xvf cli.tar.gz -C ~/` ||
echo "cli.tar.gz can not be found. Exiting" >&2 && exit 1
다음과 같습니다.
if [[ -e cli.tar.gz && ! $(tar xvf cli.tar.gz -C out) ]]; then echo "cli.tar.gz can not be found. Exiting" >&2; exit 1; fi
또는 가독성을 위해 확장되었습니다.
if [[ -e cli.tar.gz && ! $(tar xvf cli.tar.gz -C out) ]]; then
echo "cli.tar.gz can not be found. Exiting" >&2
exit 1
fi
예시 실행
견본. 압축된 패키지의 내용:
$ tar ztvf cli.tar.gz
drwxrwxr-x saml/saml 0 2013-11-13 08:26 1/
drwxrwxr-x saml/saml 0 2013-11-13 08:26 1/2/
drwxrwxr-x saml/saml 0 2013-11-13 08:26 1/2/3/
drwxrwxr-x saml/saml 0 2013-11-13 08:26 1/2/3/4/
파일 정보:
$ ls -l cli.tar.gz
-rw-rw-r-- 1 saml saml 146 Nov 13 08:27 cli.tar.gz
$ ls out/
1
다음 명령을 실행하세요.
$ if [[ -e cli.tar.gz && ! $(tar xvf cli.tar.gz -C out) ]]; then echo "cli.tar.gz can not be found. Exiting" >&2; exit 1; fi
아무 일도하지. 출력 디렉터리를 삭제하는 경우. out
:
$ mv out out_ORIG
그리고 다시 실행하세요:
$ if [[ -e cli.tar.gz && ! $(tar xvf cli.tar.gz -C out) ]]; then echo "cli.tar.gz can not be found. Exiting" >&2; fi
tar: out: Cannot chdir: No such file or directory
tar: Error is not recoverable: exiting now
cli.tar.gz can not be found. Exiting
무슨 일이에요? 우선, 일반적으로 시도하는 것처럼 if/then에서 실행 명령을 혼합하고 싶지 않습니다. 잘못될 수 있는 일이 너무 많습니다.
리팩토링 실행 #2
대신에 나는 당신(작성자)조차도 6개월 안에 이해하기 어려울 터무니없는 코드를 작성하는 대신에 나타나는 문제를 처리하는 가장 쉬운 방법을 제공하기 때문에 코드를 이렇게 구성할 것입니다.
if [[ -e cli.tar.gz ]]; then
cmdOutput=$(tar xvf cli.tar.gz -C out 2>&1);
if [[ $? != 0 ]]; then
echo "cli.tar.gz can not be found. Exiting" >&2
exit 1
fi
fi
예
$ ls -l |grep -E "cli|out"
-rw-rw-r-- 1 saml saml 146 Nov 13 08:27 cli.tar.gz
drwxrwxr-x 3 saml saml 4096 Nov 13 09:28 out
이제 명령을 실행하세요. (아무 일도 일어나지 않습니다.)
$ if [[ -e cli.tar.gz ]]; then cmdOutput=$(tar xvf cli.tar.gz -C out 2>&1); if [[ $? != 0 ]]; then echo "cli.tar.gz can not be found. Exiting" >&2; exit 1;fi;fi
$
이제 명령을 실행하십시오(dir.out이 존재하지 않음).
$ rm -fr out
$ ls -l |grep -E "cli|out"
-rw-rw-r-- 1 saml saml 146 Nov 13 08:27 cli.tar.gz
$ if [[ -e cli.tar.gz ]]; then cmdOutput=$(tar xvf cli.tar.gz -C out 2>&1); if [[ $? != 0 ]]; then echo "cli.tar.gz can not be found. Exiting" >&2; exit 1;fi;fi
cli.tar.gz can not be found. Exiting