2016-07-25 1 views
-1

나는 리눅스에 매우 익숙하고 (윈도우즈에서 온다.) 여러 시스템에서 잘 수행 할 수있는 스크립트를 작성하려고한다. 나는 이것을 위해 파이썬을 사용하려했지만 열심히 노력했다. 다음은 내가 지금까지 가지고있는 것입니다 :내가 bash로 바꿀 때 쉘 스크립트가 멈추다 - 리눅스

cd /bin 
bash 
source compilervars.sh intel64 
cd ~ 
exit #exit bash 
file= "~/a.out" 
if[! -f "$file"] 
then 
icc code.c 
fi 

#run some commands here... 

스크립트는 두 번째 줄 (bash)에 멈 춥니 다. 나는 그것을 고치는 법이나 내가 잘못하고있는지를 잘 모릅니다. 제발 조언.

또한 동일한 네트워크의 여러 시스템에서이 스크립트를 실행하는 방법에 대한 팁이 있습니까?

고마워요.

#!/bin/bash 

source /bin/compilervars.sh intel64 

file="$HOME/a.out" 

if [ ! -f "$file" ]; then 
    icc code.c 
fi 

당신은 파일에 넣고 및 chmod +x myscript와 그것을 실행 만들 것 : 나는 당신이 원하는 것 무엇을 믿는

+0

이 스크립트를 어떻게 실행하고 있습니까? 그것은 무엇을 의도합니까? 왜 bash를 처음부터 실행하기보다는 중간에 bash를 호출하려고합니까? –

+0

bash 스크립트를 작성하고 실행하는 방법에 대한 기본 지식이 있는지 확실하지 않은 경우 살펴보십시오. http://stackoverflow.com/documentation/bash/300/hello-world#t=201607251613433976444 – Sundeep

+1

스크립트를 제출하십시오. http://shellcheck.net/ 여러분이 여기에 와서 인간을 위해 디버깅 해달라고 요청하기 전에. – tripleee

답변

2

. 그런 다음 ./myscript으로 실행합니다. 또는 bash myscript으로 실행할 수도 있습니다.

스크립트가 거의 의미가 없습니다. 두 번째 줄은 새로운 bash 세션을 열지 만 종료 할 때까지 계속됩니다. 또한 디렉토리를 앞뒤로 변경하는 일은 거의 없습니다. 다른 디렉토리에 하나의 명령을 실행하려면, 하나는 일반적으로

(cd /other/place && mycommand) 

(...) 당신이 서브 쉘에서이 작업을 수행하고자하는 쉘을 지시한다. cd은 해당 하위 셸 내에서 발생하며 완료되면 cd이 다시 돌아올 필요가 없습니다. cd이 실패하면 명령이 실행되지 않습니다. 예를 들어

: 당신은 당신이 코드를 컴파일 할 때 당신이 $HOME에있어 확인 할 수 있습니다 :

if [ ! -f "$file" ]; then 
    (cd $HOME && icc code.c) 
fi 

을 ... 또는 변수 file에서 디렉토리 이름을 선택하고 사용

if [ -f "$file" ]; then 
    (cd $(dirname "$file") && icc code.c) 
fi 

= 주위에 공백없이 변수를 지정해야합니다. I 위에서 그것을 쓴 마찬가지로

거기 요구 공백 if[ ... ] 내부한다.

설명이 더 편하기 때문에 ~이 아닌 $HOME이 스크립트에서 사용되는 경향이 있습니다.

+0

이 작품! 너무 감사합니다 @ Kusalananda. 공백이 중요하다는 것을 나는 몰랐다. 알아 둘만한. 나는 그걸 더 많이 보게 될 것이다. – Samy

+0

@Samy Lines가 중요합니다. 특히 입력 할 때 중요합니다. ;-) 미안, 농담 이었어. 빈 줄은 중요하지 않습니다. 공간은 장소에서 중요합니다. 명령 뒤에 공백이 있어야합니다. '[''실제로'쉘에 내장되어있는 명령입니다 ('man [') 참조). 또한'/ bin/[','if/bin/[-f "$ file "; then' (예, 일치하는']'은 이제 이상하게 보입니까?), if test -f "$ file"와 동일합니다; 그때'. 어떻게하면 혼란에 빠질까요? ;-) – Kusalananda

1

쉘 스크립트는 터미널에 입력되는 키 스트로크의 레코드가 아닙니다. 이 같은 스크립트를 작성하는 경우 :

command1 
bash 
command2 

는 스크립트가 배쉬로 전환 한 다음 다른 쉘에서 command2을 실행하는 것을 의미하지 않습니다. bash이 실행됨을 의미합니다. 제어 터미널이있는 경우 해당 bash는 프롬프트를 표시하고 명령을 입력 할 때까지 기다립니다. bash를 종료하려면 exit을 입력해야합니다. 그런 다음 원래 스크립트는 command2과 함께 계속됩니다.

스크립트를 다른 쉘로 전환 할 방법이 없습니다. 이것을 시뮬레이트하는 방법이 있습니다. 스크립트는 다른 쉘을 사용하여 스스로 다시 실행할 수 있습니다. 그렇게하기 위해서, 스크립트는 그것이 재실행되는 것을 감지하는 로직을 포함해야한다. 그래서 다시 재발생하는 것을 막을 수 있고, 두 번 실행해서는 안되는 코드를 건너 뛸 수있다.

this script에서 나는 그러한 재실행 해킹을 구현했습니다. 그것은이 라인으로 구성

# 
# The #!/bin/sh might be some legacy piece of crap, 
# not even up to 1990 POSIX.2 spec. So the first step 
# is to look for a better shell in some known places 
# and re-execute ourselves with that interpreter. 
# 

if test x$txr_shell = x ; then 
    for shell in /bin/bash /usr/bin/bash /usr/xpg4/bin/sh ; do 
    if test -x $shell ; then 
     txr_shell=$shell 
     break 
    fi 
    done 
    if test x$txr_shell = x ; then 
    echo "No known POSIX shell found: falling back on /bin/sh, which may not work" 
    txr_shell=/bin/sh 
    fi 
    export txr_shell 
    exec $txr_shell $0 ${@+"[email protected]"} 
fi 

txr_shell 변수 (하지 표준 변수, 내 발명)이 논리가 다시 실행 한 것을 감지하는 방법입니다. 변수가 존재하지 않으면 원래의 실행입니다. 다시 실행하면 export txr_shell이므로 다시 실행 된 인스턴스는이 환경 변수를 갖게됩니다.

변수는 쉘 경로도 보유합니다. 스크립트에서 나중에 사용됩니다. SHELL 변수로 Makefile으로 전달되므로 빌드 레시피가 동일한 쉘을 사용하게됩니다. 위의 논리에서 txr_shell의 내용은 중요하지 않습니다. 부울로 사용됩니다. 존재하거나 존재하지 않습니다.

위의 코드 조각의 프로그래밍 스타일은 매우 오래된 셸에서 작동하도록 의도적으로 코딩되어 있습니다. 그렇기 때문에 현대 구문 [ -z "$txr_shell" ] 대신 test x$txr_shell = x이 사용되며 이유는 "[email protected]" 대신 ${@+"[email protected]"}이 사용되는 이유입니다.

스크립트의 나머지 부분이 재실행 트릭 덕택에 합리적이고 현대적인 셸로 실행되기 때문에 더 이상이 스타일을 스크립트에서 사용하지 않습니다.

관련 문제