파일에서 읽고 내용을 한 줄씩 실행합니다. 첫 번째 오류가 발생하면 종료됩니다.

파일에서 읽고 내용을 한 줄씩 실행합니다. 첫 번째 오류가 발생하면 종료됩니다.

do.sh나는 파일의 내용을 읽기 위해 bash 명령줄 구성을 사용하고 있습니다. 이 파일의 각 줄을 한 줄씩 실행하여 나중에 중간 줄의 오류를 처리하고 후속 내용의 실행을 중지하는 스크립트에 텍스트를 추가할 수 있도록 하려고 합니다. 내가 사용하는 구문은 다음과 같습니다

cat do.sh|while read lin;do (echo $(" $lin")) ;done
echo $amit

do.sh의 내용이 다음과 같다고 가정합니다.

amit=3
ram=/path/to/some/dir
ls >> amit.log

amit마지막으로 두 변수(예: , ) 의 내용에 액세스할 수 있어야 하며 ram명령의 출력은 오류를 파악할 수 없습니다. ls에 저장되어야 합니다 .amit.log

답변1

표준 getpoint 스크립트 사용

. ./do.sh

또는 비표준

source ./do.sh

...스크립트를 실행하고 생성된 변수를 현재 환경에 유지하는 방법(그리고 출력을 포함하는 파일을 생성하는 방법 ls) 만을 요구하는 원래 질문을 해결할 것입니다.

업데이트된 질문에서는 오류 발생 시 스크립트 소스를 즉시 종료하는 방법에 대해서도 묻습니다. "오류"는 일부 명령이 0이 아닌 종료 상태로 종료되었음을 의미한다고 가정합니다.

set -e일반적으로 첫 번째 오류 시 종료되도록 활성화된 스크립트를 실행할 수 있지만 스크립트는 반드시원천, 우리는 이것을 할 수 없습니다(현재 쉘을 종료할 것입니다). 대신 bash명령이 0이 아닌 종료 상태로 종료될 때 임의의 명령을 즉시 실행할 수 있는 함수를 사용할 수 있습니다 . 실행하려는 명령은 return오류가 발생하는 즉시 실행됩니다. 그러면 스크립트 실행이 중지되고 $?현재 셸의 종료 상태가 반환됩니다.

그래서:

trap 'err=$?; trap - ERR; return "$err"' ERR
. ./do.sh
trap - ERR

그러면 ERR트랩이 명령으로 설정됩니다 err=$?; trap - ERR; return "$err". 이 명령은 모든 오류에 대해 실행되고 종료 상태를 에 저장하며 err트랩을 설정 해제하고 오류를 셸에 반환합니다 $?(또한 종료 상태를 변수에 유지합니다 err). 마지막으로 트랩을 기본값으로 trap - ERR재설정합니다 .ERR

예:

false실패한 명령을 시뮬레이션하는 데 사용한 에 대한 호출을 포함하도록 스크립트가 수정되었습니다 . 변수는 설정되지만 amit.log파일은 생성되지 않을 것으로 예상됩니다.

$ cat do.sh
amit=3
ram=/path/to/some/dir
false
ls >> amit.log

다음 명령을 실행하세요.

$ trap 'err=$?;trap - ERR;return "$err"' ERR
$ . ./do.sh
$ trap - ERR

변수를 얻었지만 파일이 아직 생성되지 않았음을 보여줍니다.

$ printf '%s\n' "$amit" "$ram"
3
/path/to/some/dir
$ ls
do.sh

답변2

do.sh에서 변수를 가져오려면 이 방법을 사용하면 됩니다.

#!/bin/bash

. ./do.sh

echo "$amit $ram"

이전 .명령은 ./do.shdo.sh에 설정된 모든 변수에 액세스할 수 있도록 현재 환경에서 파일을 실행하도록 인터프리터에 지시합니다.

답변3

몇 가지 문제:

  • 서브셸에서 명령을 실행하고 있습니다. 하위 셸 환경의 변경 사항은 상위 셸로 전파되지 않습니다.
  • 당신은 아무것도 할당하지 않습니다. 할당은 변수 확장 이전에 발생하므로 확장 시 할당이 아닌 " $lin"명령으로 이해됩니다 . $(...)즉, amit=3다음과 같이 입력한 것처럼  이름이 지정된 명령을 실행하려고 시도합니다 "amit=3".그리고인용 부호).
    추신: 따옴표를 생략해도 do (echo $(" $lin"))도움이 되지 않습니다. 시도하지 마세요.
  • 파이프라인에서 전체 프로세스를 실행하고 있습니다. 그렇지 않은 경우 lastpipe하위 쉘에서 다시 실행됩니다. 즉, 변경 사항이 상위 쉘에 전파되지 않습니다.

이로써 모든 문제가 해결되었습니다.

#!/bin/bash
shopt -s lastpipe
cat do.sh | while read lin ; do
    eval "$lin"
done

echo "$amit $ram"

그러나 문제가 발생합니다. 누군가가 포함하도록 파일을 변경하면 어떻게 될까요 rm -rf *?

답변4

[root@x ~]# cat /tmp/sk221
amit=3
ram=/tmp/sk12

[root@x ~]# . /tmp/sk221

[root@x ~]# echo $amit
3

[root@x ~]# echo $ram
/tmp/sk12

관련 정보