bash 쉘 스크립트에서 명령을 에코하지만 실행하지 않는 방법은 무엇입니까?


11

명령을 에코 하지만 실제로 실행하지 않고 쉘 스크립트를 실행하는 방법이 있습니까?

이름이 변수에 저장된 파일을 제거하는 스크립트가 있다고 가정 해 봅시다.

#!/bin/bash
set -v
FN="filename"
rm -f ${FN}

추가 set -v하면 실행 전에 다음 명령이 에코됩니다.

$ ./scr.sh
FN="filename"
rm -f ${FN}

이제 실제로 파일을 제거하지 않고이 스크립트의 흐름을보고 싶습니다. IOW, 외부 환경 및 파일 시스템에 대한 영향을 막고 싶습니다. 이것이 가능한가?

모든 명령을 명령으로 래핑 할 수 echo는 있지만 긴 스크립트가 필요합니다.


나는 bash 스크립팅 전문가가 아니지만 다른 프로그래밍 언어로 이것을 작성한다면 모든 명령을 배열에 저장합니다. 이런 식으로 쉽게 반복하고 명령을 실행하거나 출력을 인쇄 할 수 있어야합니다.
hugo der hungrige

답변:


8

실제로 수행하지 않고 스크립트가 어떻게 실행되는지 확인하기 위해 스크립트를 단계별로 진행할 방법이 없습니다. 귀하의 예에는 if문이나 루프 가 없습니다 . 그러나 실제 스크립트에는 종종 많은 조건문이 있습니다. 어떤 브랜치를 가져올지는 종종 쉘이 이전 명령을 실행할 때 발생한 일에 따라 다릅니다. 명령을 실행하지 않으면 쉘이 어떤 출력을 생성했는지 또는 리턴 코드가 무엇인지 알 수있는 방법이 없으며 다음 조건부 분기 또는 지정 문이 종속 될 수 있습니다.

요점은 스크립트를 면밀히 조사하고 스크립트를 실행하기 전에 수행하는 작업을 알고 싶다면 나쁜 생각이 아닙니다. 그러나 실제로 가장 좋은 방법은 파일을 lessvi거나 비슷한 것을 찾아 보는 것입니다.

추가

스크립트를 개발 중이고 처음으로 스크립트를 진행하고 로직을 테스트하고 있지만 버그가있는 경우 실제로 손상을 입히지 않으려는 경우 자주 사용할 수있는 솔루션은 수정 만하는 것입니다 echo전면 에 붙여 넣어 손상을 줄 수있는 문구 .

(a) 반복 할 항목 목록을 생성하거나 변수를 설정할 값을 파일 시스템을 변경하지 않고 생성 할 수 있으며 (b) 일반적으로 충분하기 때문에 이는 일반적인 실제 스크립트에서 종종 작동합니다. 명령을 실행하면 성공한다고 가정하십시오.


감사. 당신이 언급 한 이유 때문에 정확하게 방법이 있다면 놀랍지 만 어쨌든 시도해보기로 결정했습니다. 그 이유는 네트워크의 많은 컴퓨터에서 파일을 이동하고 원격 호스트에서 일부 작업을 수행하는 스크립트를 개발하고 있기 때문입니다. 실제로 파일 시스템에 변경 사항을 커밋하기 전에 스크립트 흐름을보고 싶습니다. 파일 오류를 수정하기 위해 모든 원격 컴퓨터를
살펴 보는 것은 지루할 것입니다

1
추가 : 스크립트를 단계별로 trap read debug실행하려면 실행 된 모든 줄마다 읽은 스크립트를 시작한 다음 enter를 사용하여 천천히 단계별로 진행 할 수 있습니다 (스크립트가 길고 테스트하려는 경우 유용합니다) 처음으로).
netigger

8

나는 당신이 에코를해야한다고 생각합니다. 그러나 명령을 변수에 넣으면 켜고 끌 수 있습니다. 또한 명령은 원하는대로 기능하고 정교 할 수 있습니다.

#!/bin/bash
echo 'Debug'
  D=echo
  :>| testy
  ls -l testy
  $D rm -f testy
  ls -l testy
echo $'\n\nLive'
  D=
  :>| testy
  ls -l testy
  $D rm -f testy
  ls -l testy

!$ > ./conditional.sh
Debug
-rw-rw-r-- 1 nobody nobody 0 2013-01-18 15:28 testy
rm -f testy
-rw-rw-r-- 1 nobody nobody 0 2013-01-18 15:28 testy

Live -rw-rw-r-- 1 nobody nobody 0 2013-01-18 15:28 testy ls: cannot access testy: No such file or directory


echo / don't-echo 명령에 따옴표가 필요 D=eval했으며 실제 부분에서 사용해야 했습니다. 그러나 좋은 대답!
재스퍼

5

bash에 -x 옵션을 사용하여 플로우를 추적하지만 여전히 명령을 실행합니다.

당신이 할 수있는 최선의 방법은 그냥 에코와 같은 외부 효과가있는 명령을 에코 또는 주석 처리하는 것입니다. 적어도 모든 줄을 바꿀 필요는 없습니다.


감사. 내 질문에 해당 옵션을 언급했지만 실제로 내 문제를 해결하지는 않습니다.
ysap

죄송합니다. 모든 줄을 에코한다고 생각했습니다. -x는 이것을 몇 가지 명령으로 줄이고 평가를 보여줍니다.
parkydr

4

드라 이런에 대한 특정 방법을 모르지만 알려지지 않은 스크립트를 이해하기 위해 몇 가지 예방책을 사용할 수 있습니다.

  1. chroot 환경을 사용 하여 디버그 스크립트를 실행하십시오. 샌드 박스 역할을하며 주 시스템 파일 삭제 / 수정에 대한 보호 기능을 제공합니다.
  2. 사용 bash -n <script>을위한 구문 검사 . gnu bash 매뉴얼 https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html에서

-n Read commands but do not execute them; this may be used to check a script for syntax errors. This option is ignored by interactive shells.

  1. 스크립트를 한 번 이상 읽으십시오. user191016의 답변 에서 언급 한대로 디버그위해 echo 문을 사용할 수 있습니다 .
    • 의심 스럽거나 위험한 경향이있는 코드를 찾으십시오.
    • 예 : rm 관련, / dev / sda에 영향을주는 명령 등
  2. 항상 일반 사용자로 스크립트를 실행하고 알 수없는 스크립트를 루트로 실행하지 마십시오.
  3. 스크립트 시작시 대화식으로 파일을 수정할 수있는 명령을 작성하도록 별명정의 할 수 있습니다. 예 alias rm="rm -i" alias cp="cp -i" alias mv="mv -i" sed와 같은 스트림 편집기의 경우 sed -i(-i는 -i없이 파일을 제자리에서 수정합니다. 전체 명령을 복사하고 실행할 수 있습니다. 실제 명령 직전에 화면에 출력이 표시되고 명령을 사용하여 사용자 입력이 계속 될 때까지 기다립니다. 예 다음으로 sed -i <pattern> 교체 sed <pattern> read -p "Press any key..." sed -i <pattern>

또한 비상 데이터를 복원 할 수 있도록 항상 시스템에 백업 지점을 유지하는 것이 좋습니다.


3

수행 set –nAPPEND, 또는 n기존에 set –v명령. 그러나 이로 인해 쉘이 if또는 명령이 아닌 명령을 평가하지 않기 때문에 while운영 흐름을 너무 잘 볼 수 없습니다.


감사. 이것은 좋은 시작이지만, 언급했듯이 실제 흐름을 볼 수는 없습니다. 실제 스크립트에서 원격 호스트 목록을 통해 루프가 있습니다.
ysap

3

다음은 내가 사용하고 싶은 작은 구조입니다.

#!/bin/sh

verbose=false
really=true

# parse arguments
while [ $# -ge 1 ]
do
  case "$1" in
    -v) verbose=true ;;
    -n) really=false; verbose=true ;;
  esac
  shift
done

doCmd() {
  if $verbose; then echo "$@"; fi
  if $really; then "$@"; fi
}

doCmd make foo
doCmd rm -rf /tmp/installdir
doCmd mkdir /tmp/installdir
doCmd whatever
doCmd blah blah

2

수정이 발생하지 않도록하려면 권한없이 사용자로 스크립트를 실행할 수 있습니다.

sudo -u nobody ./scr.sh

귀하의 예에서는 FN="filename"평소와 같이 실행 됩니다. 기술적으로 명령 rm -f ${FN}을 실행하는 동안 파일을 삭제하는 데 필요한 권한이없는 사람 이 없으면 아무 일도 일어나지 않습니다.

물론 조건부 워크 플로에 문제가 발생할 수 있습니다. 사실 rm명령이 실패 스크립트의 추가 부분에 영향을 줄 수 있습니다.


우리가 결코 이해하지 못하는 것들 : 왜 아무도 루트가 루트로 요구되지 않는가?
mjohnsonengr

사용자 "nobody"는 OS에 적합하지 않지만 sudoers 파일에 "nobody"에 대한 암호없는 sudo를 허용하는 항목을 추가 할 수 있습니다.
Dennis

난 몰라 스크립트가 완료되기 전에 약간의 오류 또는 다른 오류로 인해 스크립트가 종료 된 것으로 보입니다.
Edward Falk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.