2016-11-17 3 views
4

시작한 인스턴스를 계산하는 bash 스크립트를 만들었습니다. 여기Bash 자체의 인스턴스를 잘못 계산하는 스크립트

는 (이 예에서는, 나는 wc -l로 계산하는 대신 인스턴스를 보여주는거야)된다

#!/bin/bash 
nb=`ps -aux | grep count_itself.sh` 
echo "$nb" 
sleep 20 

(물론, 내 스크립트가 count_itself.sh 이름)를 실행하면 나는이 두 줄을 반환 할 것으로 예상하지만,이 세 가지 결과 : & 플래그를 실행하면

[email protected]:/# ./count_itself.sh 
root 16225 0.0 0.0 12400 1176 pts/0 S+ 11:46 0:00 /bin/bash ./count_itself.sh 
root 16226 0.0 0.0 12408 564 pts/0 S+ 11:46 0:00 /bin/bash ./count_itself.sh 
root 16228 0.0 0.0 11740 932 pts/0 S+ 11:46 0:00 grep count_itself.sh 

을 (즉,

[email protected]:/# ./count_itself.sh & 
[1] 16233 
[email protected]:/# ps -aux | grep count_itself.sh 
root  16233 0.0 0.0 12408 1380 pts/0 S 11:48 0:00 /bin/bash ./count_itself.sh 
root  16240 0.0 0.0 11740 944 pts/0 S+ 11:48 0:00 grep --color=auto count_itself.sh 

내 질문은 : 왜 스크립트 내부의 ps -aux 실행이 예상보다 한 줄 이상을 반환하지 배경, 수동으로 ps -aux 비트를 실행하기에, 내가 원하는 것입니다있는이 반환?

또는 다른 말로하면, 첫 번째 예제에서 ID가 16226 인 프로세스가 생성되는 이유는 무엇입니까?

EDIT (대부분의 사람들이 내 질문을 오해하는 것 같은) 다음 bash 실행 /bin/bash ./count_itself.sh의 두 인스턴스를 반환하는 이유는 그것이 grep count_itself.sh를 반환하지 왜 궁금하네요

.

편집 2 :

물론, 나는이 문제를 방지하고 스크립트가 할 수있는 방법을 찾고 있어요 한 번만 /bin/bash ./count_itself.sh을 반환합니다.

+2

'\'ps -aux | grep count_itself.sh \'는 하위 셸, 즉 하위 프로세스에서 실행됩니다. 따라서 스크립트를 실행하는 쉘은 분기되고 자식은'ps -aux | grep count_itself.sh' 명령을 사용하십시오. – Leon

+0

나는 제안한다 : nb ='ps -aux | grep [c] ount_itself.sh – Cyrus

+2

'ps -aux | grep count_itself.sh' 당신의 grep은 count_itself의 인스턴스와 같습니다. regex – Stargateur

답변

1

마지막으로 부분적으로 질문에서 영감 못생긴 하나 임에도 불구하고 @TomFenech 그의 answer에 연결하는 방법을 발견 :

#!/bin/bash 
nb=$(ps f | grep '[c]ount_itself.sh' | grep -v ' \\_') 
echo "$nb" 
sleep 20 

실행 : (내가 이해 한 것과)

[email protected]:/# ./count_itself.sh & 
[1] 17733 
[email protected]:/# ./count_itself.sh 
17733 pts/1 S  0:00 \_ /bin/bash ./count_itself.sh 
17739 pts/1 S+  0:00 \_ /bin/bash ./count_itself.sh 

설명 : 하나는 이미 BG에서 실행하는

[email protected]:/# ./count_itself.sh 
17725 pts/1 S+  0:00 \_ /bin/bash ./count_itself.sh 

실행이

  • ps f가 반환 활성 프로세스 트리
  • 01 23,516,
  • grep '[c]ount_itself.sh'
  • 를 구성 프로세스에 대응 count_itself.sh

다음 반환

17808 pts/1 S+  0:00 \_ /bin/bash ./count_itself.sh 
17809 pts/1 S+  0:00  \_ /bin/bash ./count_itself.sh 
  • grep -v ' \\_' 4 개 공간 (탭 당량)를 포함하는 열을 제외 \_ 만 보여주는 경우에 이전 명령을 제한
4

grep의 출력은 ps의 표준 문제입니다.

하나의 솔루션이이 인수를 사용하여 프로세스의 이름은 대괄호하지만 패턴을 포함하고 있기 때문에 당신의 grep 인스턴스 자체와 일치하지 않는 것을 의미한다 문자

nb=$(ps -aux | grep '[c]ount_itself.sh') 

주위에 약간의 대괄호를 추가하는 것입니다 그것은 일치하지 않습니다.

주석에서 언급했듯이 공백을 유지하려면 변수 주위에 큰 따옴표를 사용해야합니다.

결과에 동일한 쉘의 인스턴스가 두 개인 것으로 보이는 이유는 명령 대체가 서브 쉘 내에서 실행되기 때문입니다. 상위 프로세스 만 표시하는 것에 대한 자세한 내용은 this question을 참조하십시오.

+0

내 질문을 편집했는데'ps -aux'가 서브 쉘 실행을 리턴하지 못하게하는 방법이 있습니까? – roberto06

+0

링크를 추가하려면 편집 됨. –

2

프로세스 대체를 위해서는 상위 쉘이 하위 쉘을 시작해야합니다. 즉, 하위 쉘에서 지정된 명령을 포크하고 실행해야합니다. 부모 쉘이 환경 (변수, 현재 작업 디렉토리, 트랩)에 대한 변경에 영향을받지 않고 $(...)에 포함 된 스크립트가 영향을받지 않도록하려면이 작업이 필요합니다.

예 :

$ cat test.sh 
#!/bin/bash 

a=1 
b="$(a=2; echo abc)" 
echo "a=$a" 
echo "b=$b" 
$ ./test.sh 
a=1   # Note that the variable 'a' preserved its value 
b=abc 

그것은 당신이 스크립트의 추가 인스턴스를보고있는 것을 포크 (fork)의 결과이다.

원칙적으로 스크립트가 합법적으로 자체의 다른 인스턴스 (하위 프로세스로 실행 됨)를 시작할 수 있기 때문에 이러한 원치 않는 프로세스를 출력에서 ​​확실하게 제거 할 수 있다고 생각하지 않습니다. 그 두 경우 사이.

해킹 된 해결책 중 하나는 스크립트가 지정된 위치 (예 : /tmp/your_script_name)에 호출시 PID 파일을 만들고 종료시 제거하도록하는 것입니다.

2

나는 다음 방법 제안 :

모든 과정을 제외을 부모가 자신을 것을 :

ps --pid $$ -N -a | grep count_itself.sh 

이 모든 부모는 자신 (아님 명령을 보여 의미하므로이 당신의 그렙 과정과로 포크 프로세스를 제외 실행 카운터 문장)

+0

'--pid $$'플래그만으로 두 줄을 계속 울리고,'-N' 플래그를 추가하면 아무 것도 울리지 않습니다. 나는 어딘가에 중간 결과를 찾고 있어요 : P – roberto06

+0

만약'-N' 플래그가 아무 것도 반환하지 않는다면 당신이 유일한 인스턴스이기 때문에 실행되고있는 것 같아요. 셀 수 있다면 1을 더할 수 있습니다. 그 결과. –