실행 중 셸 스크립트 편집


95

실행중인 쉘 스크립트를 편집하고 변경 사항이 실행중인 스크립트에 영향을 미치도록 할 수 있습니까?

csh 스크립트의 특정 사례에 대해 궁금합니다. 배치가 여러 가지 빌드 버전을 실행하고 밤새도록 실행됩니다. 작업 중에 뭔가가 발생하면 들어가서 추가 명령을 추가하거나 실행되지 않은 명령을 주석 처리하고 싶습니다.

가능하지 않은 경우이를 수행 할 수있는 쉘 또는 배치 메커니즘이 있습니까?

물론 시도해 보았지만 효과가 있는지 확인하기까지 몇 시간이 걸릴 것이며, 뒤에서 무슨 일이 일어나고 있는지 아닌지 궁금합니다.


1
실행중인 스크립트에 대한 스크립트 파일을 편집 한 결과 두 가지 결과를 보았습니다. 1) 전체 내용을 메모리로 읽은 것처럼 변경 사항이 무시되거나 2) 명령의 일부를 읽은 것처럼 스크립트가 오류와 함께 충돌합니다. 그것이 스크립트의 크기에 달려 있는지 모르겠습니다. 어느 쪽이든, 나는 그것을 시도하지 않을 것입니다.
Paul Tomblin

간단히 말해서, 자체 참조 / 호출이 아닌 한 아니요.이 경우 기본 스크립트는 여전히 이전 스크립트입니다.
Wrikken 2010 년

여기에는 두 가지 중요한 질문이 있습니다. 1) 실행중인 스크립트에 명령을 정확하고 안전하게 추가하려면 어떻게해야합니까? 2) 실행중인 스크립트를 수정하면 어떻게됩니까?
Chris Quenelle

3
문제는 셸이 전체 스크립트 파일을 읽은 다음 실행하여 스크립트를 실행하는지 아니면 실행될 때 부분적으로 읽어서 스크립트를 실행하는지입니다. 나는 그것이 무엇인지 모른다; 지정되지 않을 수도 있습니다. 두 가지 행동에 따라 피해야합니다.
Keith Thompson

답변:


-68

스크립트는 그렇게 작동하지 않습니다. 실행중인 사본은 편집중인 소스 파일과 독립적입니다. 다음에 스크립트가 실행될 때 가장 최근에 저장된 소스 파일 버전을 기반으로합니다.

이 스크립트를 여러 파일로 나누어 개별적으로 실행하는 것이 좋습니다. 이렇게하면 실행 시간이 실패 할 수 있습니다. (즉, 배치를 하나의 빌드 플레이버 스크립트로 분할하고 각 스크립트를 개별적으로 실행하여 문제를 일으키는 원인을 확인합니다).


68
나는 그 반대를 관찰했습니다. 편집 된 bash 스크립트를 실행하면 파일이 bash의 스크립트 읽기 파일 위치 아래로 이동하는 것처럼 보이기 때문에 실행중인 스크립트가 충돌 할 수 있습니다.
Tilman Vogel 2012 년

10
여러 시스템에 대한 내 경험상 실행 복사본은 디스크 파일과 독립적이지 않으므로이 문제가 쉘 스크립트 프로그래밍에서 매우 놀랍고 중요한 이유입니다.
Chris Quenelle 2013 년

6
디스크에있는 파일과는 확실히 독립적 이지 않습니다 . 쉘은 일반적으로 128 바이트 또는 4096 바이트 또는 16384 바이트의 블록으로 스크립트를 읽고 새 입력이 필요할 때만 다음 블록을 읽습니다. (당신은 스크립트를 실행하는 쉘에 lsof를 같은 일을하고 여전히 파일을 열있어 볼 수 있습니다.)
mirabilos

5
아니요. 실제로 스크립트를 편집하면 프로세스가 실패합니다.
Erik Aronesty 2013-10-17

8
당신은 정확하지 않습니다. 구현 및 스크립트에서 호출되는 실제 명령에 따라 버퍼링됩니다. stdout이 파일로 리디렉션되는지 여부에 관계없이 많은 요소가 있으며 귀하의 대답은 단순히 정확하지 않습니다.
GL2014

51

그것은 않습니다 내 환경에서 최소한의 bash에서, 그러나에 영향을 미치는 매우 불쾌한 방법 . 이 코드를 참조하십시오. 첫째 a.sh:

#!/bin/sh

echo "First echo"
read y

echo "$y"

echo "That's all."

b.sh:

#!/bin/sh

echo "First echo"
read y

echo "Inserted"

echo "$y"

# echo "That's all."

하다

$ cp a.sh run.sh
$ ./run.sh
$ # open another terminal
$ cp b.sh run.sh  # while 'read' is in effect
$ # Then type "hello."

제 경우 출력은 항상 다음과 같습니다.

여보세요
여보세요
그게 다야.
그게 다야.

(물론 자동화하는 것이 훨씬 낫지 만 위의 예는 읽을 수 있습니다.)

이것은 예측할 수 없으므로 위험합니다. 가장 좋은 해결 방법은 , 여기에 설명 된 바와 같이 중괄호의 모든을 넣어 닫는 중괄호 전에, "exit"를 넣어 . 함정을 피하기 위해 연결된 답변을 잘 읽으십시오 .

[추가됨] 정확한 동작은 하나의 추가 줄 바꿈에 따라 달라지며 아마도 Unix 버전, 파일 시스템 등에 따라 달라집니다. 단순히 영향을보고 싶다면 b.sh 앞뒤에 "echo foo / bar"를 추가하면됩니다. "읽기"줄.


3
음, 애정이 보이지 않아요. 내가 뭔가를 놓치고 있습니까?
사용자 알 수없는

정확한 동작은 하나의 추가 개행 문자 에 따라 달라지며 아마도 유닉스 풍미, 파일 시스템 등에 따라 달라질 수 있습니다. 단순히 영향을보고 싶다면 b.shecho foo / bar / baz의 10 줄을 추가하여 확대 하면됩니다. dave4220과 저의 대답의 요지는 그 효과를 예측하기 쉽지 않다는 것입니다. (BTW 명사 "애정"수단 "사랑"=)
테이 카 kazura

예, 매우 고장났습니다. 나는 해결책이 있습니다 (아래). 무엇보다 위험한 것은 SVN / rsync에 / 자식 업데이트
에릭 Aronesty

40

이것을 시도하십시오 ...라는 파일을 만드십시오 bash-is-odd.sh:

#!/bin/bash
echo "echo yes i do odd things" >> bash-is-odd.sh

이것은 bash가 실제로 "당신이가는대로"스크립트를 해석한다는 것을 보여줍니다. 실제로 장기간 실행되는 스크립트를 편집하면 임의의 문자를 삽입하는 등 예측할 수없는 결과가 발생합니다. 이유는 무엇입니까? bash는 마지막 바이트 위치에서 읽기 때문에 편집하면 현재 읽고있는 문자의 위치가 이동합니다.

Bash는 한마디로이 "기능"때문에 매우 안전하지 않습니다. svn 및 rsyncbash 스크립트와 함께 사용하면 기본적으로 결과를 "병합"하기 때문에 특히 문제가 발생합니다. 제자리에서 편집합니다. rsync이를 수정하는 모드가 있습니다. svn과 git은 그렇지 않습니다.

해결책을 제시합니다. 다음과 같은 파일을 만듭니다 /bin/bashx.

#!/bin/bash
source "$1"

이제 #!/bin/bashx스크립트에서 사용하고 항상 bashx대신 bash. 이렇게하면 문제가 해결 rsync됩니다. 스크립트를 안전하게 사용할 수 있습니다.

@ AF7에서 제안 / 테스트 한 대체 (인라인) 솔루션 :

{
   # your script
} 
exit $?

중괄호는 편집을 방지하고 종료는 추가를 방지합니다. 물론 bash가 -w(전체 파일) 과 같은 옵션을 제공하거나 이와 같은 작업을 수행했다면 훨씬 나을 것입니다.


1
Btw; 여기에 마이너스에 대응하는 플러스가 있으며 편집 된 답변이 마음에 들기 때문입니다.
Andrew Barber

1
나는 이것을 추천 할 수 없다. 이 해결 방법에서는 위치 매개 변수가 1 씩 이동합니다. 또한 $ 0에는 값을 할당 할 수 없습니다. 이는 단순히 "/ bin / bash"를 "/ bin / bashx"로 변경하면 많은 스크립트가 실패 함을 의미합니다.
teika kazura

1
이러한 옵션이 이미 구현되었다고 알려주세요!
AF7

10
내 친구 Giulio가 제안한 간단한 해결책은 스크립트 시작 부분에 {를 삽입하고 스크립트 끝에}를 삽입하는 것입니다. Bash는 메모리에있는 모든 것을 읽어야합니다.
AF7

1
@ AF7 친구의 솔루션 개선 : {your_code; } && 종료; 끝에 추가 된 줄도 실행되지 않습니다.
korkman

17

스크립트를 함수로 나누고 함수가 호출 될 때마다 source별도의 파일에서 스크립트를 호출 합니다. 그런 다음 언제든지 파일을 편집 할 수 있으며 실행중인 스크립트는 다음에 소싱 될 때 변경 사항을 선택합니다.

foo() {
  source foo.sh
}
foo

이 기술을 한동안 효과적으로 사용하여 실행중인 장기 실행 빌드 스크립트를 업데이트했습니다. 각 쉘 스크립트를 구현하기 위해 두 개의 파일을 가질 필요가 없도록 현재 파일을 파일 끝까지 읽도록하는 기술을 배우고 싶습니다.
Chris Quenelle

3

좋은 질문! 이 간단한 스크립트가 도움이되기를 바랍니다.

#!/bin/sh
echo "Waiting..."
echo "echo \"Success! Edits to a .sh while it executes do affect the executing script! I added this line to myself during execution\"  " >> ${0}
sleep 5
echo "When I was run, this was the last line"

Linux에서는 실행중인 .sh에 대한 변경 사항이 실행 스크립트에 의해 실행되는 것처럼 보입니다. 충분히 빠르게 입력 할 수 있다면!


2

흥미로운 추가 정보-Python 스크립트를 실행하는 경우 변경되지 않습니다. (이것은 쉘이 Python 스크립트를 실행하는 방법을 이해하는 사람에게는 분명하지만이 기능을 찾는 사람에게는 유용한 알림이 될 수 있다고 생각하는 사람에게는 분명합니다.)

내가 만들었다:

#!/usr/bin/env python3
import time
print('Starts')
time.sleep(10)
print('Finishes unchanged')

그런 다음 다른 셸에서 이것이 잠자고있는 동안 마지막 줄을 편집합니다. 이 작업이 완료되면 변경되지 않은 줄이 표시됩니다. 아마도 .pyc? Ubuntu와 macOS에서도 마찬가지입니다.


1

나는 csh를 설치하지 않았지만

#!/bin/sh
echo Waiting...
sleep 60
echo Change didn't happen

그것을 실행하고, 읽을 마지막 줄을 빠르게 편집하십시오.

echo Change happened

출력은

Waiting...
/home/dave/tmp/change.sh: 4: Syntax error: Unterminated quoted string

음.

쉘 스크립트에 대한 편집은 다시 실행될 때까지 적용되지 않는 것 같습니다.


2
표시하려는 문자열을 따옴표로 묶어야합니다.
user1463308 jul.

2
실제로 편집자가 생각한대로 작동하지 않는다는 것을 증명합니다. 많은 편집기 (vim, emacs 포함)는 라이브 파일이 아닌 "tmp"파일에서 작동합니다. vi / emacs 대신 "echo 'echo uh oh'>> myshell.sh"를 사용해보고 새로운 내용이 출력되는 것을 확인하십시오. 더 나쁜 것은 ... svn과 rsync도 이렇게 편집합니다!
Erik Aronesty 2013 년

3
-1. 이 오류는 편집중인 파일과 관련이 없습니다. 아포스트로피를 사용하고 있기 때문입니다! 작은 따옴표로 작동하여 오류가 발생합니다. 전체 문자열을 큰 따옴표로 묶고 다시 시도하십시오.
Anonymous Penguin

5
오류가 발생했다는 사실은 편집이 의도 한 효과가 없음을 나타냅니다.
danmcardle 2015 년

@danmcardle 누가 압니까? 아마도 bash는 보았다 Change didn'ned.
Kirill Bulygin 2018

1

이것이 모두 단일 스크립트에 있으면 작동하지 않습니다. 그러나 하위 스크립트를 호출하는 드라이버 스크립트로 설정하면 하위 스크립트를 호출하기 전에 또는 반복하는 경우 다시 호출하기 전에 변경할 수 있으며이 경우 이러한 변경 사항을 믿습니다. 실행에 반영됩니다.


0

나는 아니오를 들었습니다 ... 그러나 약간의 간접적 인 것은 어떻습니까?

BatchRunner.sh

Command1.sh
Command2.sh

Command1.sh

runSomething

Command2.sh

runSomethingElse

그렇다면 BatchRunner가 제대로 작동하기 전에 각 명령 파일의 내용을 편집 할 수 있어야합니까?

또는

더 깨끗한 버전은 BatchRunner가 한 번에 한 줄씩 연속적으로 실행되는 단일 파일을 찾습니다. 그렇다면 첫 번째 파일이 실행되는 동안이 두 번째 파일을 편집 할 수 있어야합니다.


... 그것은 그들을 실행하는 메모리로로드 경우 변경이 문제의 주요 프로세스가 시작되지 않습니다 일단 궁금해
에릭 Hodonsky

0

스크립팅에 Zsh를 대신 사용하십시오.

AFAICT, Zsh는 이러한 실망스러운 행동을 나타내지 않습니다.


이것이 bash보다 Zsh를 선호하는 이유 # 473입니다. 나는 최근에 실행하는 데 10m가 걸리는 오래된 bash 스크립트를 작업하고 있으며 완료되기를 기다리는 동안 편집 할 수 없습니다!
Micah Elliott

-5

일반적으로 스크립트를 실행하는 동안 편집하는 것은 드문 일입니다. 당신이해야 할 일은 당신의 운영에 대한 통제 점검을하는 것입니다. 조건을 확인하려면 if / else 문을 사용하십시오. 뭔가 실패하면 이렇게하고, 그렇지 않으면 그렇게하세요. 그게 갈 길입니다.


실제로 작업 중에 배치 작업을 수정하기로 결정하는 것보다 스크립트 실패에 대한 것이 적습니다. IE는 내가 컴파일하고 싶은 것이 더 있거나 이미 대기열에있는 특정 작업이 필요하지 않다는 것을 깨달았습니다.
ack

1
스크립트에 엄격하게 추가 하면 bash가 예상대로 수행합니다!
Erik Aronesty 2010 년
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.