【问题标题】:Sourcing a script file in bash before starting an executable在启动可执行文件之前在 bash 中获取脚本文件
【发布时间】:2010-04-09 10:48:29
【问题描述】:

我正在尝试编写一个 bash 脚本,它“包装”用户想要调用的任何内容(及其参数),在实际调用它之前获取一个固定文件。

澄清一下:我有一个“ConfigureMyEnvironment.bash”脚本,必须在启动某些可执行文件之前获取该脚本,所以我想要一个“LaunchInMyEnvironment.bash”脚本,您可以使用如下:

LaunchInMyEnvironment <whatever_executable_i_want_to_wrap> arg0 arg1 arg2

我尝试了以下 LaunchInMyEnvironment.bash:

#!/usr/bin/bash
launchee="$@"
if [ -e ConfigureMyEnvironment.bash ];
     then source ConfigureMyEnvironment.bash;
fi

exec "$launchee"

我必须使用“launchee”变量来保存 $@ var,因为在执行 source 之后,$@ 变为空。

无论如何,这不起作用,失败如下:

myhost $ LaunchInMyEnvironment my_executable -h
myhost $ /home/me/LaunchInMyEnvironment.bash: line 7: /home/bin/my_executable -h: No such file or directory
myhost $ /home/me/LaunchInMyEnvironment.bash: line 7: exec: /home/bin/my_executable -h: cannot execute: No such file or directory

也就是说,“-h”参数似乎被视为可执行文件名的一部分,而不是作为参数......但这对我来说没有任何意义。 我也尝试使用 $* 而不是 $@,但没有更好的结果。

我做错了什么?

安德烈亚。

【问题讨论】:

    标签: bash exec word-wrap


    【解决方案1】:

    您是否尝试过删除 exec 命令中的双引号?

    【讨论】:

    • 不可能,在这种情况下,“-h”甚至不会传递给 my_executable
    • 对不起,你的答案是正确的,实际上删除 exec 命令中的引号是正确的做法。我被可执行文件中的一个问题愚弄了,该问题没有正确处理“-h”选项,所以我认为它根本没有收到“-h”......
    【解决方案2】:

    试试这个:

    #!/usr/bin/bash
    typeset -a launchee
    launchee=("$@")
    if [ -e ConfigureMyEnvironment.bash ]; 
      then source ConfigureMyEnvironment.bash; 
    fi 
    exec "${launchee[@]}"
    

    这将使用数组来存储参数,因此它甚至可以处理诸如“空格分隔字符串”和“带有 ; 的字符串”之类的调用

    更新:简单示例

    test_array() { abc=("$@"); for x in "${abc[@]}"; do echo ">>$x<<"; done; } test_array "abc def" ghi

    应该给

    >>abc def>ghi
        

    【讨论】:

    • 我试过了,但我得到的失败与我原来的帖子完全相同:myhost $ LaunchInMyEnvironment my_executable -h myhost $ /home/me/LaunchInMyEnvironment.bash: line 7: /home/bin/ my_executable -h:没有这样的文件或目录 myhost $ /home/me/LaunchInMyEnvironment.bash:第 7 行:exec:/home/bin/my_executable -h:无法执行:没有这样的文件或目录
    • 这意味着您正在使用一些奇怪的 bash。我已经在 bash 版本 2.05b.0(1)-release 中尝试过这种情况。尝试获取仅打印一些内容以检查该功能的源文件。并确保将[@](方括号和“at”符号)放在执行执行的位置。还要检查您是否已将("$@")(带有花括号)放入变量中。在我的情况下,typeset 的第一行不是必需的,但是...
    【解决方案3】:

    您可能想试试这个(未经测试):

    #!/usr/bin/bash
    launchee="$1"
    shift
    if [ -e ConfigureMyEnvironment.bash ];
         then source ConfigureMyEnvironment.bash;
    fi
    
    exec "$launchee" $@
    

    exec 的语法是 exec command [arguments],但是因为您引用了 $launchee,所以它被视为单个参数 - 即命令,而不是命令及其参数。另一种变化可能是简单地做:exec $@

    【讨论】:

    • 正如我在原始帖子中所说,我不能直接使用 $@ 因为它似乎在“采购”时被清除了,这就是我使用 $launchee 的原因,所以 exec "$launchee" $@对我来说似乎不可行
    【解决方案4】:

    不用exec就正常执行

    #!/usr/bin/bash
    launchee="$@"
    if [ -e ConfigureMyEnvironment.bash ];
         then source ConfigureMyEnvironment.bash;
    fi
    
    $launchee
    

    【讨论】:

    • exec - 表示用新的 ($launchee) 替换进程的当前内容。您的变体将产生另一个进程并等待完成(两个进程 $launchee 和 bash 等待它)。省略引号可能会导致正常执行,但如果您指定包含空格的参数(即带空格的文件名),它将被解释为多个参数。
    • 正如任何人指出的那样,不同之处在于这只会产生一个新进程(与我使用 exec 的版本相比),但问题是相同的:即没有引号它可以工作但没有t 获取任何参数,使用双引号我得到了与原始帖子中显示的相同的失败
    【解决方案5】:

    尝试划分你的参数列表:

    ALL_ARG="${@}"
    可执行文件="${1}"
    Rest_of_Args=${ALL_ARG##$Executable}

    然后尝试:

    $Executable $Rest_of_Args
    (或执行 $Executable $Rest_of_Args)

    调试器

    【讨论】:

      猜你喜欢
      • 2016-09-19
      • 2011-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-28
      • 1970-01-01
      相关资源
      最近更新 更多