그래요터미널에서 bash 스크립트 가져오기, 따라서 오류 종료
set -o errexit
터미널을 닫고 다른 터미널을 연 다음 일부 변수를 재설정해야 하기 때문에 매우 짜증나는 터미널이 종료됩니다.
지금까지 사용하여
command || return
스크립트의 줄이 내가 원하는 대로 작동하고 있습니다.
set -o errexit
해야 할 일...하지만 한 줄/명령만이 아닌 전체 스크립트가 완료되기를 원합니다.
사이트 설정을 위한 명령으로 가득 찬 파일이 있지만 명령을 실행하고 싶지 않습니다.
파일의 각 줄에 대해
다른 설정 옵션이 있거나 터미널을 종료하는 대신 "반환"하는 다른 옵션이 있습니까?
--단지 명확성을 위해, 스크립트를 종료하고 터미널에서 실행 중인 서비스를 종료하기 위해 Ctrl+C를 누른 것과 동일한 상태로 터미널을 두고 싶습니다. command || return
이 방법. 하지만 || return
파일의 모든 줄에 추가하고 싶지는 않습니다 . 그래서 저는 set -o errexit
터미널이 닫히지 않는 이와 같은 것을 찾고 있습니다 .
- - 노트: 두 줄을 포함하는 단순 스크립트(super.sh)를 만듭니다.
create_path=~/Desktop/site_builder/create.sh
source $create_path blah
set -o errexit
create.sh 상단에 배치됩니다 .
내가 예상한 대로 정확하게 작동합니다. 그러나 터미널에서 호출하는 대신 다른 bash 스크립트를 호출하기 위해 두 줄로 파일을 생성해야 하는 것은 정말 어리석은 일입니다. 어 어 어
여기 몇 가지 예가 있어요.
super.sh에서
#!/bin/bash
create_path=~/Desktop/site_builder/create.sh
source $create_path blah
create.sh에서
#!/bin/bash
set -o errexit
#line below this is a line that fails and will cause the script to stop and return to the terminal as expected
sed "s/@@SITE_NAME@@/$dirname"
~/Desktop/site_builder/template_files/base.html > ~/Desktop/$dirname/templates/base.html # a line with a stupid error
터미널에서:
$ bash super.sh
출력은 예상대로입니다.
my-mac$
이것은 작동합니다. 정말 짜증나는 해결책입니다.
나생각하다이상적으로는 터미널을 닫지 않고 super.sh 파일이 아닌 터미널에서 멍청한 super.sh 파일의 내용을 실행하세요 :D. 이것이 내가하려는 일에서 일어나는 일입니다.
터미널 명령:
my-mac$ source $create_path blah
create.sh에는 아직set -o errexit
이것은 터미널의 출력입니다.
sed: 1: "s/@@SITE_NAME@@/blah": unterminated substitute in regular expression
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.
[Process completed]
그러면 터미널이 정지됩니다. Ctrl+C가 작동하지 않고, Ctrl+D도 작동하지 않습니다.
그렇지 않은 경우 create.sh 파일의 아무 곳에서나 명령문을 사용 set -o errexit
하면 command || return
(터미널에서 super.sh를 호출하는 대신) 터미널에서 직접 superser.sh의 행을 실행하는 동안 원하는 것을 얻을 수 있습니다. 하지만 이것도 실용적인 해결책은 아니다.
노트:( )
서브셸 생성에 대한 @terdon의 답변이 마음에 들었기 때문에 전체 스크립트 주위에 중괄호를 사용하여 답변에서 보여준 것처럼 터미널 대신 스크립트를 통해 서브셸을 생성하게 되었습니다 . 그의 대답도 효과가 있습니다.
답변1
파일을 얻으려면 안전 장치를 사용하십시오.
source the-source-file || true
...그러면 실패하더라도 전체 명령이 실패하지 않습니다 source
.
답변2
이것이 내가 달성해야 하는 작업에 작동하는 유일한 방법입니다(가상 환경을 생성한 다음 활성화한 다음 bash 스크립트에서 요구 사항을 설치).
다음과 같은 스크립트에서 하위 쉘/하위 쉘을 생성하십시오.
바보 파일 .sh
(
set -o errexit
#bunch of commands
#one line fails
)
다음을 사용하여 어리석은 파일을 실행하십시오.
source stupid_file.sh <file arguments here> || true
마치다.
**절하다**
(Jeff와 Terdon의 크레딧)
답변3
set -o errexit
대신 다음을 사용할 수 있습니다 trap
.
trap 'trap - ERR RETURN; kill -INT $$ ; return' ERR RETURN
kill -INT $$
동작은 비슷 exit
하지만 스크립트가 소스로 제공되면 아무 작업도 수행하지 않습니다(대신 실행됩니다 return
)(입력 프롬프트가 신호를 포착하여 쉘이 종료되는 것을 방지하기 때문에 이것이 작동한다고 생각합니다).
trap - ...
스크립트가 종료된 후에 실행되지 않도록 트랩을 비활성화합니다.
답변4
간단한 해결 방법으로 현재 셸 내에서 셸을 실행하고 그곳에서 소스 코드를 얻을 수 있습니다. 그것은 다음과 같습니다:
새 터미널을 열고 원하는 대로 모든 것을 설정하세요. 일부 환경 변수 등을 언급하셨습니다. 여기에서 설정하세요.
해당 터미널에서 새 쉘을 시작하십시오. 예를 들어,
bash
.당신의 일을 하세요. 스크립트를 받으세요. 종료되면 첫 번째 셸로 이동하고 모든 것이 여전히 설정됩니다. 다시 실행
bash
하면 정상으로 돌아옵니다.
이를 설명하기 위해 다음 스크립트를 만들었습니다. 이 스크립트는 얻으려고 하면 실패합니다.
$ cat /home/terdon/scripts/bar.sh
set -o errexit
var='bar
중첩된 쉘 세션을 시작한 다음 이를 가져오면 어떤 일이 발생하는지 살펴보겠습니다(명령의 휴대용 이름을 사용한다는 점에 유의하세요 source
. .
; source
는 bashism입니다).
parent-shell $ bash ## start a new shell
child-shell $ . ~/scripts/bar.sh
bash: /home/terdon/scripts/bar.sh: line 2: unexpected EOF while looking for matching `''
parent-shell $
보시다시피 구문 오류로 인해 소스 스크립트가 종료되고 이로 인해 쉘 세션이 종료되지만 이는 중첩 세션이므로 모든 변수가 여전히 설정된 원래 상위 쉘로 돌아갑니다. 이제 새 셸을 다시 실행하면 돌아가서 스크립트를 가져올 수 있습니다.