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.sh
do.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