나는 다음 코드를 사용합니다.이 스크립트나는 이것을 사용하여 WordPress 사이트를 업데이트합니다.
#!/bin/bash
drt="/var/www/html"
for dir in ${drt}/*/; do
if pushd "$dir"; then
wp plugin update --all --allow-root
wp core update --allow-root
wp language core update --allow-root
wp theme update --all --allow-root
popd
fi
done
모든 WordPress 인스턴스를 한 번에 업데이트하는 방법을 찾던 중 이 코드에서 사용된 특정 패턴에 대해 배웠습니다 pushd
.popd
이 코드에 세그먼트가 포함된 이유가 확실하지 않습니다 if-fi
.
내 질문
기본적으로 동일한 패턴을 갖지만 if-fi
세그먼트가 없도록 구문을 어떻게든 변경할 수 있습니까?
예를 들어 다음과 같이 변경합니다.
if pushd "$dir";
popd
commands
fi
나는 다음과 같은 의사 코드를 갖게 될 것입니다 :
pushd "$dir";
commands
popd
내가 이걸 왜 물어?
if-fi
선언(의사 코드) 없이 컴퓨터에 다음과 같이 말할 수 있는 방법을 상상할 수 있습니다 .
for dir in ${drt}/*; do pushd "$drt"; then
commands
popd
노트
답변에 다른 접근 방식을 포함할 수도 있습니다(즉, 전혀 포함하지 않음)
pushd
.popd
답변1
또한@Olorin이 작성함여기에는 약간의 오해가 있을 수 있다고 생각합니다. 먼저 for y in ${x}/*; do pushd "$y"; then
결과는
bash: 예상치 못한 토큰 "then" 근처에 구문 오류가 있습니다.
두번째,들여쓰기로 인해 오해가 발생할 수 있습니다.실제로 일어난 일에 대해. 원래 코드의 올바른 형식의 버전:
for y in ${x}/*/
do
if pushd "$y"
then
command1
command2
popd
fi
done
다시 말해서,모두 command1
, 초기 성공이 발생한 경우 command2
에만 실행됩니다 . 대신 쓴다면popd
pushd
for y in ${x}/*/
do
pushd "$y"
command1
command2
popd
done
그리고 errexit
가드가 없으면 실패 pushd
나 실패가 popd
스크립트의 나머지 부분에 영향을 미치지 않습니다. 이로 인해 잘못된 디렉토리가 실행 command1
되고 입력되어 다른 디렉토리로 되돌아갈 수 있습니다.command2
이 코드와는 아무 관련이 없습니다.이는 비참한 결과를 초래할 수 있습니다.
마지막으로 하고 싶은 말은pushd
+ 명령 +는 popd
안티 패턴입니다언어에 더 많은 컨텍스트(따라서 인지적 오버헤드와 위험)를 추가하고 복잡한 컨텍스트가 이미 큰 문제이기 때문입니다. 이 문제를 해결하는 가장 일반적인 방법은 다음과 같이 명령에 경로(절대 경로 권장)를 전달하는 것입니다.
for y in "$x"/*/
do
command1 "$y"
command2 "$y"
done
답변2
실패 하면 pushd
어떻게 되나요 ? 이러한 디렉터리에서 명령을 실행하는 경우 pushd
명령을 계속하기 전에 성공 여부를 분명히 확인해야 합니다.
답변3
if를 사용하는 것은 디렉토리 변경 실패에 대한 합리적인 보호 장치입니다.
디렉터리가 실행 가능하지 않은 경우(x 권한 없음) 이 코드는 상위 디렉터리에서 명령을 실행합니다.
#!/bin/bash
drt="/var/www/html"
for dir in "${drt}"/*/
do pushd "$dir"
pwd
popd
done
몇 개의 디렉토리를 구축하고 소유자 및 권한을 변경하십시오.
$ mkdir -p /var/www/html/{one,two}
$ sudo chown user:user /var/www/html/{one,two}
$ sudo chmod o-x /var/www/html/two
$ ./script
/var/www/html/one ~/temp
/var/www/html/one
~/temp
./script: line 5: pushd: ./var/www/html/two/: Permission denied
~/temp
./script: line 7: popd: directory stack empty
Pushd 명령은 오류를 발생시키지만 pwd 명령은 ~/temp 디렉터리에서 실행됩니다(오류 후에 인쇄되는 ~/temp 값에 유의하십시오). 이는 분명히 잘못된 일을 할 위험이 있습니다. 이 스크립트와 비교해보세요:
#!/bin/bash
drt="./var/www/html"
for dir in "${drt}"/*/
do if pushd "$dir" 2>/dev/null
then
pwd
popd
fi
done
새 스크립트가 실행되었습니다.
$ ./script
/var/www/html/one ~/temp
/var/www/html/one
~/temp
또는 더 나은 방법은 다음과 같습니다.
#!/bin/bash
drt="./var/www/html"
for dir in "${drt}"/*/
do if pushd "$dir" 2>/dev/null
then
pwd
popd
else
echo "Failed to change to dir=$dir" >&2
exit 7
fi
done
실행되면 다음과 같이 인쇄됩니다.
$ ./script
/var/www/html/one ~/temp
/var/www/html/one
~/temp
Failed to change to dir=/var/www/html/two/
답변4
gnu-find를 사용하면 다음을 수행할 수 있습니다.
find ${drt} -maxdepth 1 -type d -execdir command1 ";" -execdir command2 ";"
모든 find 구현에 -execdir 옵션이 있는 것은 아닙니다.