이러한 제약을 만족시킬 수 있는 방법은 없습니다

이러한 제약을 만족시킬 수 있는 방법은 없습니다

zsh는 좋은 것을 제공합니다후크 기능, chpwd사용자가 디렉터리를 변경한 후 실행되는 기능을 포함합니다.

# zsh only
function greet() { echo 'hi'; }
chpwd_functions+=("greet")
cd .. # hi
pushd # hi
popd  # hi

나는 이것을 bash에서 에뮬레이트하려고합니다.

제한 요인:

  • 대화형 쉘과 비대화형 쉘 모두에서 작동해야 합니다. 이는 다음과 같은 것에 의존할 수 없다는 것을 의미한다고 생각합니다.$PROMPT_COMMAND
  • cd디렉토리를 변경하는 명령(예: pushdpopd) 과 함께 작동하기를 원하므로 재정의할 수 없습니다.
  • 실행해야 해뒤쪽에사용자의 명령을 실행하므로 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_functionszshell 후크와 같은 것을 제공하는 것이 유일하게 좋은 해결책인 것 같지만 이를 올바르게 에뮬레이트하는 것은 불가능해 보입니다.

답변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내 예에서는 지정된 디렉터리에 변경(수정, 생성, 삭제)이 발생하면 다음 명령이 다시 시작됩니다.

관련 정보