zsh는 좋은 것을 제공합니다후크 기능, chpwd
사용자가 디렉터리를 변경한 후 실행되는 기능을 포함합니다.
# zsh only
function greet() { echo 'hi'; }
chpwd_functions+=("greet")
cd .. # hi
pushd # hi
popd # hi
나는 이것을 bash에서 에뮬레이트하려고합니다.
제한 요인:
- 대화형 쉘과 비대화형 쉘 모두에서 작동해야 합니다. 이는 다음과 같은 것에 의존할 수 없다는 것을 의미한다고 생각합니다.
$PROMPT_COMMAND
cd
디렉토리를 변경하는 명령(예:pushd
및popd
) 과 함께 작동하기를 원하므로 재정의할 수 없습니다.- 실행해야 해뒤쪽에사용자의 명령을 실행하므로
trap "my_function" DEBUG
"먼저 문제가 있는 명령을 실행한 다음 이 작업도 수행하세요..."라고 말할 수 없으면 작동하지 않습니다.$BASH_COMMAND
자동 실행을 피할 수 있다는 것을 알았습니다.$BASH_COMMAND
만약에extdebug
활성화됨그리고트랩 함수는 1을 반환하지만 강제로 실행하고 싶지는 않으며 성공적인(그러나 수정된) 명령을extdebug
반환하는 것이 잘못된 것 같습니다.1
마지막 부분인 "사용자 명령에 따라 실행"은 현재 나를 혼란스럽게 합니다. 만약 내가할 수 있는각 명령 다음에 함수를 실행하면 마지막으로 확인한 이후 디렉터리가 변경되었는지 확인할 수 있습니다. 예를 들어:
function check_pwd() {
# true in a new shell (empty var) or after cd
if [ "$LAST_CHECKED_DIR" != "$PWD" ]; then
my_function
fi
LAST_CHECKED_DIR=$PWD
}
나는 올바른 길을 가고 있습니까, 아니면 더 나은 길이 있습니까?사용자가 디렉토리를 변경한 후 bash에서 명령을 실행하는 방법은 무엇입니까?
답변1
이러한 제약을 만족시킬 수 있는 방법은 없습니다
내 한계를 감안할 때 bash에서는 이 문제를 해결할 방법이 없는 것 같습니다. 일반적으로 가능한 해결책은 다음과 같습니다.
cd
,pushd
및 를 재정의하여popd
디렉터리를 변경하는 모든 명령이 후크 기능을 먼저 실행하도록 합니다. 그러나 이로 인해 문제가 발생할 수 있습니다. 1) 재정의는 원래 명령만큼 신중하게 수행되어야 하며 동일한 종료 코드를 반환해야 하며, 2) 여러 도구가 이 접근 방식을 사용하는 경우 함께 잘 작동하지 않습니다.- 후크 기능을 먼저 실행하려면 환경이 변경될 때 실행될 수 있는 모든 명령을 재정의하세요. 이런 명령어가 많아서 어렵네요
trap 'my_function' DEBUG
이렇게 하면 모든 명령이 후크 기능을 실행합니다. 이는 1) 모든 명령 전에 실행되고 2) 실행되기 때문에 차선책입니다.앞으로cd
, 대신 3) 디버깅 기능은 하나만 있을 수 있으므로 다른 도구에서 이 접근 방식을 사용하면 함께 잘 작동하지 않습니다.$PROMPT_COMMAND
먼저 실행할 Hook 함수를 재정의합니다 . 이는 비대화형 셸에서는 작동하지 않으며 다른 도구에서 프롬프트 명령을 정의하는 경우 함께 잘 작동하지 않기 때문에 차선책입니다.
간단히 말해서, bash가 chpwd_functions
zshell 후크와 같은 것을 제공하는 것이 유일하게 좋은 해결책인 것 같지만 이를 올바르게 에뮬레이트하는 것은 불가능해 보입니다.
답변2
관리자가 cd 정의를 변경하는 것을 좋아하지 않는 경우, 또 다른 옵션은 이 디렉터리 내에서 환경을 사용하는 모든 명령을 재정의하는 것입니다.
for c in cmd1 cmd2 cmd3 cmd4 cmd5 ; do
eval "$c() { check_pwd ; command $c \"\$@\" ; }"
done
PWD 후크 및 디렉터리 내 구성은 필요할 때만 처리되므로 이는 매우 효율적입니다.
귀하의 예제 check_pwd 함수에서는 다음을 변경할 수 있습니다.
my_function
도착하다:
my_function "$PWD"
새로운 cwd를 통과하기 위해(아마도 더 모듈화되고 테스트 가능함).
답변3
설치하다이노티파이 도구배포판에 따라 다릅니다.
inotifywait -emodify,create,delete -m /path/to/directory | while read line; do service httpd reload; done
httpd
내 예에서는 지정된 디렉터리에 변경(수정, 생성, 삭제)이 발생하면 다음 명령이 다시 시작됩니다.