나는 내가 만들려고 하는 잠재적인 오류에 대해 쉘이 나에게 경고해주기를 원합니다.
. 이후에 명령이 cmd2
실행되지 않도록 하려면 어떻게 해야 합니까?cmd1
예를 들어:
$ tar tf file.tar
$ rm !$
여기서는 내용을 추출하는 대신 파일을 나열했다는 사실을 잊어버렸습니다.
저는 이전 명령의 이름과 반환 값, 그리고 현재 명령을 기반으로 선택하는 일반적인 솔루션을 찾고 있습니다.
답변1
shopt -s histverify
Bash에서는 기록이 한 단계로 확장 및 실행되는 것을 중지하도록 설정할 수 있습니다 . 여기서 위의 내용은 을 처음 누를 때 $ rm !$
로 확장되어 다시 눌러 실행하기 전에 확인하거나 편집할 수 있습니다 . 보다 일반적인 해결책은 다음과 같습니다.$ rm file.tar
EnterEnter
"내 말대로 하세요"당신의 의도를 추측하는 프로그램이 필요합니다.
답변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
특정 경우에는 원하는 작업을 수행하지 않았더라도 오류가 발생하지 않았으므로 두 번째 명령이 계속 실행됩니다.