한 명령이 다른 명령 다음에 실행되지 않도록 방지

한 명령이 다른 명령 다음에 실행되지 않도록 방지

나는 내가 범할 수 있는 실수에 대해 쉘이 나에게 경고해주기를 원합니다.

NET cmd2에서 명령이 실행되지 않도록 하는 방법cmd1

예를 들어:

$ tar tf file.tar
$ rm !$

여기서는 내용을 추출하는 대신 파일을 나열했다는 사실을 잊어버렸습니다.

현재 명령뿐만 아니라 이전 명령의 이름과 반환 값을 기반으로 선택하는 일반적인 솔루션을 찾고 있습니다.

답변1

shopt -s histverifyBash에서는 기록이 한 단계로 확장 및 실행되는 것을 방지할 항목을 설정할 수 있습니다 . 여기에서 처음 누르면 위의 내용이 $ rm !$확장되어 다시 실행을 누르기 전에 검토하거나 편집할 수 있습니다. 보다 일반적인 솔루션은 다음으로 이동합니다.$ rm file.tarEnterEnter
"내가 원하는 대로 하세요"영토, 당신의 의도를 추측하는 프로그램이 필요합니다.

답변2

당신은 많은 일반적인 답변을 요구하고 있지만 어느 정도는 상대적으로 쉬울 것입니다.

그러나 bash이 문제를 해결하는 데 도움이 될 수 있는 일반적인 메커니즘이 두 개 이상 있습니다. 프롬프트에서 무엇이든 실행한 후에 실행될 변수 PROMPT_COMMAND를 설정할 수 있습니다.

$ PROMPT_COMMAND='echo BOFH says hi!'
BOFH says hi!
$ man man
BOFH says hi!
$

이를 사용하여 마지막으로 입력한 명령을 저장한 다음 다시 읽어 나중에 사용하기 위해 메모리에 저장할 수 있습니다(이 경우 기록 확장은 작동하지 않습니다).

$ PROMPT_COMMAND='history -a; tail -n1 ~/.bash_history'
PROMPT_COMMAND='history -a; tail -n1 ~/.bash_history'
$ wc < test.sh | grep .
 5 11 63
wc < test.sh | grep .

이제 논리 부분이 나옵니다. 이는 전적으로 귀하에게 달려 있습니다. 질문의 예를 차단하기 위해 매우 간단한 논리를 사용해 보겠습니다. 기억해야 할 점은 bash 기능이 여전히 작동하므로 모든 것을 한 줄, 단일 변수에 넣을 필요가 없다는 것입니다.

$ # define the logic check
$ checkSanity() { grep -q "tar  *[tf][[:alpha:]]*[tf] " <<< "$@" && echo "be careful, don't delete this"; }
checkSanity() { grep -q "tar  *[tf][[:alpha:]]*[tf] " <<< "$@" && echo "be careful, don't delete this"; }
$ # feed it the last command
$ PROMPT_COMMAND='history -a; last=$(tail -n1 ~/.bash_history); checkSanity "$last"'
$ # simple test
$ tar tf test.sh 2>/dev/null 
be careful, don't delete this
$ tar xf test.sh 2>/dev/null 
$

물론 이 접근 방식은 PEBKAC를 방지하는 데 유용하지만(특히 sleep 3끝에 추가하는 경우) 다음 명령 자체가 중단되지는 않습니다.

그렇다면진짜원하는 것은 미리 실행되는 DEBUG신호(예 : )를 포착합니다. trap 'echo "I am not deterministic, haha"' DEBUG출력/작업이 두 배가 되므로 이 두 가지 방법을 결합할 때는 주의하십시오.

$ df
/.../
$ trap 'tail -n1 ~/.bash_history' DEBUG
df
df
trap 'tail -n1 ~/.bash_history' DEBUG
trap 'tail -n1 ~/.bash_history' DEBUG

트랩이 명령을 중단하려면 해당 트랩을 활성화해야 합니다 extdebug( shopt -s extdebug). 또한 기록을 계속 저장하고 다시 읽을 필요가 없지만 $BASH_COMMAND앞으로 나올 명령을 확인할 수 있습니다. 그런 다음 논리 검사기가 잘못된 경우를 감지하면 1을 반환하고 그렇지 않으면 0을 반환하는지 확인하면 됩니다.

          extdebug
                  If set, behavior intended for use by debuggers is enabled:
    /.../
                  2.     If  the command run by the DEBUG trap returns a non-zero value, the next
                         command is skipped and not executed.


$ checkSanity() { if grep -q "tar  *[tf][[:alpha:]]*[tf] " <<< "$1"; then  echo "be careful, don't delete this"; return 1; fi; }
$ trap 'checkSanity "$BASH_COMMAND"' DEBUG
$ # simple test
$ tar tf test.sh 2>/dev/null 
be careful, don't delete this
$ tar xf test.sh 2>/dev/null 
$

답변3

이 경우 명령의 오류 경고 를 통해 이점을 얻을 수 있습니다 rm.

쉘 초기화 스크립트( bash, so 가정)에서 또는 별칭을 사용할 ~/.bashrc수 있습니다 .rm-i-I

alias rm="rm -i"

~에서man 1 rm

   -i     prompt before every removal

   -I     prompt once before removing more than three files, or when
          removing recursively.  Less intrusive than -i, while still
          giving protection against most mistakes

보다 일반적인 질문은 "나 자신으로부터 시스템을 어떻게 보호합니까?"입니다.전에 논의한. 요컨대,당신이하고있는 일에주의를 기울이십시오, 필요한 경우에만 root명령을 실행합니다.

답변4

귀하의 특정 상황에 따라 다음과 같이 할 것입니다.

tar tf file.tar
if [ -f file ]; then   # Assuming you meant to extract a file
  rm -f file.tar
else
  echo "file is missing. Command failed."
fi

오류를 확인하고 첫 번째 명령이 성공한 경우에만 다음 명령을 실행하려는 경우

some_command && another_command

그러나 특정 경우에는 원하는 작업을 수행하지 않더라도 오류가 없기 때문에 두 번째 명령이 계속 실행됩니다.

관련 정보