2010-11-23 2 views
8

다른 명령의 출력을 적절한 위치로 리디렉션하는 bash 스크립트를 작성하고 있습니다. 기본적으로 쉘/명령 줄에서 스크립트를 호출하면 STDOUT으로 출력을 보내려고합니다. 그러나 bash 스크립트가 다른 응용 프로그램 (예 : 다른 bash 스크립트, 일부 응용 프로그램 또는 내 경우에는 굉장 창 관리자의 멋진 프롬프트 플러그인)에서 실행될 때 출력을 다른 곳으로 리디렉션하고 싶습니다.쉘이나 다른 스크립트/응용 프로그램에서 bash 스크립트가 호출되었는지 확인하십시오.

bash에서 스크립트가 호출 된 방법을 알 수있는 방법이 있습니까?

+1

다른 방법은 출력 자체를 파이프하는 래퍼 스크립트를 사용하는 것입니다. 그래서, 굉장한 창 관리자는 script-wrapper.sh를 호출합니다.이 줄에는 "./script.sh >> awesome.log"가 포함되어 있습니다. – laher

+1

쉘 스크립트 사용자로서 스크립트가 너무 영리하지 않으려 할 때 선호합니다 . 파일에서 출력을 원한다면 파일에 직접 넣을 수 있습니다. 파일에 출력을 보내기 위해 스크립트에 래퍼 나 플래그를 제공하면 (예 :'-o filename') 간단하고 명확하지만 이상적입니다. –

+0

좋은 지적이지만, 나는 이것을 단순하게하고 싶다. 문제의 명령은 Taskwarrior입니다. 나는 단지'task add blah blah'를 타이핑 할 수 있고 내가 타이핑 한 곳을 걱정하지 않아도되고 싶다. 매번 리디렉션이나 옵션을 입력해야하는 경우 편리하지 않기 때문에 사용하지 않을 것입니다. –

답변

16

이 시도 :이 경우 당신은 또한 표준 입력을 확인합니다 좀 더 다양한 조건 (파일 기술자 0)을 할 수 있습니다 명령 줄에서 실행되거나 스크립트 내에서 백그라운드로 실행되었습니다. 이 두 가지를 구분하려면 다음을 수행하십시오.

ps -o stat= -p $$ 

에는 배경 화되지 않은 경우 "+"가 포함됩니다.

(&)
Run   $$ $PPID 
CL   S+ Ss 
CL&   S  Ss+ 
Script  S+ S+ 
Script&  S  S 
Script(&) S  Ss 
Script&(&) S  NULL 

자식 스크립트가 백그라운드로 된 의미 & 그것은 백그라운드로하고 실행하는 ("스크립트"를 의미 것입니다) 부모 스크립트를 의미

여기에 테이블입니다. CL은 명령 행을 의미합니다. NULL은 ps 출력이 null이고, $PPID이 "1"임을 의미합니다. man ps에서

는 :

s is a session leader 
    + is in the foreground process group 

은이 답변은 GNU ps에 기반 주목해야한다,하지만 (OS의 X 포함) BSD에 대한 매뉴얼 페이지는 유사한 기능을 나타냅니다. 그리고 GNU ps은 BSD 기능을 포함하는 하이브리드입니다.

+2

"Script"는 질문의 대상이되는 스크립트가 아니라 상위 스크립트를 의미합니다. –

+0

아주 좋은 솔루션입니다. –

-1

당신은 부모의 프로세스 이름에 부모 변수를 설정 한 다음 화면에 인쇄 할

PARENT=`ps --no-heading -o %c -p $PPID` 
    echo $PARENT 

이 같은 $ PPID

뭔가를 사용할 수 있습니다.

그런 다음 몇 가지를 넣을 수 있다면 $ 학부모의 값에 따라 문

HTH

+0

직접 테스트했는지 아니면 다른 * bash * 스크립트에서 "bash"라고 인쇄했는지에 상관없이 테스트했습니다. – ndemou

+0

@ndemou 우분투 16.04, 커널 4.4.0-53에서 확인하고 5 년 후에도 여전히 "bash"를 출력합니다. – WinEunuuchs2Unix

7

나는 당신이 정말 알고 싶은 것은 표준 출력이 터미널인지 아닌지 믿습니다. 대화 상자가 있으면 대화식 세션이라고 (거의) 안전하게 가정 할 수 있습니다. 다음 단편을 시도

if [[ -t 1 ]]; then 
     echo "Terminal" 
else 
     echo "Not-a-terminal" 
fi 

[[ -t 1 ]] 명령은 상기 파일 디스크립터 1 (즉, 표준 출력)은 단말인지 아닌지를 확인하는 것이다.

편집 :

이 아닌 터미널 표준 출력을 나타냅니다 있습니다 당신은 파이프 다른 프로그램에 출력을하는 경우. 결과가 "S"를 포함하는 경우 (소문자)

ps -o stat= -p $PPID 

:

[[ -t 0 || -t 1 ]] 
+0

그러나 stdout이 터미널에없는 경우 (예 : 파이프에있을 때) 명령 줄에서 실행되는지 여부를 알고 싶을 수 있습니다. –

+0

@Dennis : 나는 이것을위한 보편적 인 또는 마법의 해결책이 없다고 생각합니다. PPID 방법은 효과적이지만 다른 스크립트를 통해 스크립트가 호출 된 경우에도 실패합니다. – thkala

+0

당신은 세 번째 레벨에 대해 이야기하고 있습니까? 스크립트 호출 스크립트 호출 스크립트? 내 대답에 기술을 사용하여 해당 스크립트가 명령 줄에서 실행되었는지 여부를 확인할 수 있습니다. –

1

이것은이 주제에 관한 다른 게시물에서 수정 한 기능입니다. 상위까지 모든 상위 프로세스를 $shells 변수에 나열된 항목과 비교합니다. 완료되면 $iscli은 0 또는 1로 설정됩니다. 0으로 설정하면 쉘에서 실행되었거나 쉘을이 용도로 충분히 고려한 것입니다. 1로 설정하면 승인되지 않은 프로그램이 관련되었음을 알 수 있습니다. 나는 각각 다른 출력을 제공하고자 할 때 셸과 PHP를 통해 실행하고자하는 스크립트에 이것을 사용합니다.

$iscli 값이 필요하기 전에 매개 변수없이 처음에 함수를 호출해야합니다.

function top_level_parent_pid { 

    scriptname="${0##*/}" 
    shells="^bash|^init|^screen|^sh|^ssh|^su|${scriptname}" 

    pid=${1:-$$} 
    pidname="`ps --no-heading -o %c -p ${pid}`" 
    stat=($(</proc/${pid}/stat)) 
    ppid=${stat[3]} 
    ppidname="`ps --no-heading -o %c -p ${ppid}`" 
    isclitest="`echo "${ppidname}" | grep -iv -E "${shells}"`" 

    until [ "${ppid}" -eq "1" ] || [ "${iscli}" = "1" ]; do 

      if [[ -n "${isclitest}" ]]; then 

        iscli="1" 

       else 

        iscli="0" 


        top_level_parent_pid ${ppid} 
      fi 
    done 
} 
관련 문제