나는 내가 범할 수 있는 실수에 대해 쉘이 나에게 경고해주기를 원합니다.
NET 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
그러나 특정 경우에는 원하는 작업을 수행하지 않더라도 오류가 없기 때문에 두 번째 명령이 계속 실행됩니다.