문제

질문:

  • 무엇 커널을 할 경우 쉘 스크립트로 라인에는?
  • 어떻게 커널을 알고 있는 인터프리터를 실행?

설명:

나는 최근에 작성하고 싶어 래퍼 /usr/bin/env 기 때문에 나는 CGI 환경을 허용하지 않을 설정 경로 변수를 제외하고,전 세계적으로(는 물론 sucks!).

그래서 저는 생각했죠,"좋아.자 설정 PREPENDPATH 설정 경로 에서 래퍼 env.".결과 스크립트(여기라 env.1)은 다음과 같았습니다.

#!/bin/bash
/usr/bin/env PATH=$PREPENDPATH:$PATH $*

처럼 보이는 작동합니다.확인 방법 그들은 둘 다 반응을 설정한 후,PREPENDPATH:

$ which /usr/bin/env python
/usr/bin/env
/usr/bin/python

$ which /usr/bin/env.1 python
/usr/bin/env
/home/pi/prepend/bin/python

완벽한!지금까지,그래서 좋은.하지만 보면 어떻게 되나"Hello World!".

# Shebang is #!/usr/bin/env python
$ test-env.py
Hello World!

# Shebang is #!/usr/bin/env.1 python
$ test-env.1.py
Warning: unknown mime-type for "Hello World!" -- using "application/*"
Error: no such file "Hello World!"

나는 뭔가가 꽤 근본적인 대 UNIX.

난 잃은 후,소스 코드의 원 환경.그것은 환경 및 실행 프로그램(또는 그래서 그것을 나에게 보인...).

도움이 되었습니까?

해결책

첫째,당신은 아주 드물게 사용 $* 당신은 거의 항상 사용 "$@" 대신 합니다.의 숫자가 여기서 질문에 그래서 설명하는 상세한 이유.

-두 번째 env 명령은 두 가지를 사용합니다.중 하나 인쇄하는 것입니다 현재는 환경;다른 것을 완전히 통제 환경의 명령을 실행하는 경우.세 번째 사용하여,당신을 보여주는,수정하는 환경,그러나 솔직하게 할 필요가 없는 껍질 있는 아주 처리할 수 있습니다.

태 1:

env

모 2:

env -i HOME=$HOME PATH=$PREPENDPATH:$PATH ... command args

이 버전이 취소되는 모든 상속된 환경 변수를 및 실행 command 으로 정확하게 환경 설정에 의해는 백분율=value 옵션이 있습니다.

세 번째 모드-을 개정하는 환경에 덜 중요하기 때문에 당신이 할 수 있는 미세한 정기적(문)껍질입니다.(즉,"C"쉘을 다시 거기에 다른 질문들에 대한 답변을 설명하는 것.) 예를 들어,당신은 완벽하게 잘:

#!/bin/bash
export PATH=${PREPENDPATH:?}:$PATH
exec python "$@"

이 주장 $PREPENDPATH 로 설정하면 빈 문자열이 아 환경에서,그리고 그 앞에 추가 그것을 $PATH, 및 수출에 새 경로를 설정합니다.그런 다음 사용하는 새로운 경로를 실행합니다 python 프로그램 관련 인수입니다.이 exec 대체 쉘 스크립트로 python.이 매우 다르다:

#!/bin/bash
PATH=${PREPENDPATH:?}:$PATH exec python "$@"

표면적으로,이것은 동일합니다.그러나,이것이 실행됩 python 에서 찾은 기존의 경로는,이기는 하지만 새 값으로의 경로에서 프로세스의 환경입니다.그래서 예제에서,당신은 끝까지 실행하는 파이썬서 /usr/bin 고서 /home/pi/prepend/bin.

귀하의 상황에서,나는 것 아마 사용 env 고 그냥 사는 적절한 변종의 스크립트는 명시적으로 수출합니다.

env 명령은 특이하기 때문에 그것을 인정하지 않을 두 번 돌진을 분리 옵션의 나머지 부분에서 명령입니다.이것은 부분하지 않기 때문에 많은 옵션,그리고 부분에 있기 때문에 명확하지 않지는 백분율=value 야 할 옵션이 올 전 또는 후 두 번 돌진합니다.

내가 실제로 시리즈의에 대한 스크립트를 실행하는(서로 다른 버전의)데이터베이스 서버입니다.이러한 스크립트를 정말 사용 env (고 무리의 집에서 재배 프로그램)하 제어 서로가 서로의:

#!/bin/ksh
#
# @(#)$Id: boot.black_19.sh,v 1.3 2008/06/25 15:44:44 jleffler Exp $
#
# Boot server black_19 - IDS 11.50.FC1

IXD=/usr/informix/11.50.FC1
IXS=black_19
cd $IXD || exit 1

IXF=$IXD/do.not.start.$IXS
if [ -f $IXF ]
then
    echo "$0: will not start server $IXS because file $IXF exists" 1>&2
    exit 1
fi

ONINIT=$IXD/bin/oninit.$IXS
if [ ! -f $ONINIT ]
then ONINIT=$IXD/bin/oninit
fi

tmpdir=$IXD/tmp
DAEMONIZE=/work1/jleffler/bin/daemonize
stdout=$tmpdir/$IXS.stdout
stderr=$tmpdir/$IXS.stderr

if [ ! -d $tmpdir ]
then asroot -u informix -g informix -C -- mkdir -p $tmpdir
fi

# Specialized programs carried to extremes:
#   * asroot sets UID and GID values and then executes
#   * env, which sets the environment precisely and then executes
#   * daemonize, which makes the process into a daemon and then executes
#   * oninit, which is what we really wanted to run in the first place!
# NB: daemonize defaults stdin to /dev/null and could set umask but
#     oninit dinks with it all the time so there is no real point.
# NB: daemonize should not be necessary, but oninit doesn't close its
#     controlling terminal and therefore causes cron-jobs that restart
#     it to hang, and interactive shells that started it to hang, and
#     tracing programs.
# ??? Anyone want to integrate truss into this sequence?

asroot -u informix -g informix -C -a dbaao -a dbsso -- \
    env -i HOME=$IXD \
        INFORMIXDIR=$IXD \
        INFORMIXSERVER=$IXS \
        INFORMIXCONCSMCFG=$IXD/etc/concsm.$IXS \
        IFX_LISTEN_TIMEOUT=3 \
        ONCONFIG=onconfig.$IXS \
        PATH=/usr/bin:$IXD/bin \
        SHELL=/usr/bin/ksh \
        TZ=UTC0 \
    $DAEMONIZE -act -d $IXD -o $stdout -e $stderr -- \
    $ONINIT "$@"

case "$*" in
(*v*) track-oninit-v $stdout;;
esac

다른 팁

Wikipedia 기사에 대해 신중하게 읽어야합니다 오두막.

시스템이 Shebang에 해당하는 마법 번호를 볼 때 execve Shebang 이후의 주어진 경로에서 스크립트 자체를 인수로 제공합니다.

주어진 파일이기 때문에 스크립트가 실패합니다 (/usr/bin/env.1) 아니다 실행 파일,하지만 셰 잔에 의해 시작됩니다 ....

이상적으로, 당신은 그것을 사용하여 해결할 수 있습니다 ... env 이 라인을 Shebang으로 스크립트에서 다음과 같습니다.

#!/usr/bin/env /usr/bin/env.1 python

Linux에서는 작동하지 않습니다. "/usr/bin/env.1 python"길로 (인수를 나누지 않음)

그래서 내가 보는 유일한 방법은 env.1 c

편집 : 아무도 나를 믿지 않는 것 같습니다 ^^, 그래서 나는 단순하고 더러운 것을 썼습니다. env.1.c:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>


const  char* prependpath = "/your/prepend/path/here:";

int main(int argc, char** argv){
  int args_len = argc + 1;
  char* args[args_len];
  const char* env = "/usr/bin/env";
  int i;

  /* arguments: the same */
  args[0] = env;
  for(i=1; i<argc; i++)
    args[i] = argv[i];
  args[argc] = NULL;

  /* environment */
  char* p = getenv("PATH");
  char* newpath = (char*) malloc(strlen(p)
                 + strlen(prependpath));
  sprintf(newpath, "%s%s", prependpath, p);
  setenv("PATH", newpath, 1);

  execv(env, args);
  return 0;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top