的问题:

  • 什么是仁做,如果你坚持一个壳-脚本到家当行?
  • 如何在核知道哪些解释程序启动?

解释:

最近,我想写一个包装 /usr/bin/env 因为我CGI环境不允许我设置的 路径 可变的,除了全球(这当然吸!).

所以我想,"OK.让我们集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.它设置的环境,并启动该程序(或所以,在我看来...).

有帮助吗?

解决方案

首先,你应该很少使用 $* 你应该几乎总是使用 "$@" 代替。还有一些问题在这里所解释的来龙去脉,为什么。

第二- env 命令有两个主要的用途。一个打印当前的环境;其他的是要完全控制环境的命令时运行。第三使用,其中你表明,修改环境,但坦率地说,没有必要,炮弹是完全有能力处理你。

模式1:

env

模式2:

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

这个版本中取消所有继承的环境变量和运行 command 正是环境组通过的ENVVAR=值的选择。

第三模式修订环境-是较不重要因为你可以这样做,现有规则(文明)的炮弹。(这意味着"不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 命令是不寻常的,因为它不承认双重划为单独的选项,从其余的命令。这部分是因为它并不需要很多选项,并在部分是因为它不清楚是否ENVVAR=值的选择应该来之前或之后的双重破折号。

我实际上有一系列脚本用于运行(不同版本的)数据库服务器。这些脚本,真正使用 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

其他提示

你应该仔细读《维基百科条约 家当.

当你的系统会看到神奇的号码对应的命令,也不会 execve 在给道路后命令并让脚本本身作为一个参数。

你的脚失败,因为该文件得到(/usr/bin/env.1)是不是 一个可执行, 但开始本身通过一个命令....

理想的是,你能解决它。 env 在你的脚本,这一行为命令:

#!/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