【问题标题】:How do I run a program with a different working directory from current, from Linux shell?如何从 Linux shell 运行具有与当前不同工作目录的程序?
【发布时间】:2010-10-21 15:28:45
【问题描述】:

使用 Linux shell,如何使用与当前工作目录不同的工作目录启动程序?

例如,我有一个二进制文件helloworld,它在当前目录中创建文件hello-world.txt

此文件位于目录/a 内。

目前,我在目录/b 中。我想启动我的程序运行../a/helloworld 并在第三个目录/c 中的某处获取hello-world.txt

【问题讨论】:

  • 我发现su 在运行任何-c 命令之前将工作目录重置为您指定的用户的主目录的困难方式。这对我很有帮助。
  • 我发布这个问题已有 12 年了,今天我自己查了一下,因为我不记得该怎么做。
  • 返回带有a:visited 链接的SO 帖子并且已经在上面投了赞成票是一回事。当你是提问者,甚至是回答者时,这是另一回事。应该有一个徽章……“健忘”

标签: linux shell environment


【解决方案1】:

如果您总是希望它转到 /C,请在编写文件时使用绝对路径。

【讨论】:

    【解决方案2】:

    一种方法是创建一个包装外壳脚本。

    shell 脚本会将当前目录更改为 /c,然后运行 ​​/a/helloworld。一旦 shell 脚本退出,当前目录将恢复到 /b。

    这是一个 bash shell 脚本示例:

    #!/bin/bash
    cd /c
    /a/helloworld
    

    【讨论】:

      【解决方案3】:

      这样调用程序:

      (cd /c; /a/helloworld)
      

      括号会产生一个子shell。然后,此子 shell 将其工作目录更改为 /c,然后从 /a 执行 helloworld。程序退出后,子 shell 终止,将您返回到父 shell 的提示符,在您开始的目录中。

      错误处理: 避免在未更改目录的情况下运行程序,例如当拼写错误/c 时,使helloworld 的执行有条件:

      (cd /c && /a/helloworld)
      

      减少内存使用:为避免在 hello world 执行时让 subshel​​l 浪费内存,请通过 exec 调用 helloworld

      (cd /c && exec /a/helloworld)
      

      [感谢 Josh and Juliano 提供改进此答案的提示!]

      【讨论】:

      • 有什么方法可以将参数传递给这个shell?就像 1 美元和 2 美元一样?
      • @segfault:子shell可以完全访问周围的范围。
      • 您可以通过 $*、$@ 或 "$@" 传递所有参数(如果您希望参数尊重双引号)
      • 如果我将此行添加到 /etc/rc.d/rc.local 会起作用吗?
      • 整个() 结构将包含最后一个命令的退出代码。您可以直接通过链接或检查 $? 来检查。
      【解决方案4】:
      sh -c 'cd /c && ../a/helloworld'
      

      【讨论】:

      • 用于 FreeBSD 的 jexec 在指定工作目录的 jail 中执行命令。
      【解决方案5】:

      类似于David Schmitt 的回答,加上 Josh 的建议,但不会让 shell 进程运行:

      (cd /c && exec /a/helloworld)
      

      这种方式更类似于您通常在 shell 上运行命令的方式。要查看实际差异,您必须使用每个解决方案从另一个 shell 运行 ps ef

      【讨论】:

      【解决方案6】:

      如果您想在程序中执行此操作,那么我会执行以下操作:

      #include <unistd.h>
      int main()
      {
        if(chdir("/c") < 0 )  
        {
           printf("Failed\n");
           return -1 ;
        }
      
        // rest of your program...
      
      }
      

      【讨论】:

      • 他想在 shell 脚本中而不是在 C 中执行此操作。此外,对二进制文件进行子处理是一个可怕的想法。
      【解决方案7】:

      我一直认为 UNIX 工具应该写成过滤器,从标准输入读取输入并将输出写入标准输出。如果可能,您可以更改 helloworld 二进制文件以将文本文件的内容写入标准输出而不是特定文件。这样您就可以使用 shell 在任何地方写入文件。

      $ cd ~/b
      
      $ ~/a/helloworld > ~/c/helloworld.txt
      

      【讨论】:

      • +1 表示正确,尽管答案只是外围的答案。
      【解决方案8】:

      为什么不保持简单

      cd SOME_PATH &amp;&amp; run_some_command &amp;&amp; cd -

      最后一个“cd”命令将带您回到最后一个 pwd 目录。这应该适用于所有 *nix 系统。

      【讨论】:

      • 你是写@mezhaka,应该考虑到:)
      • 警告:如果run_some_command 失败,cd - 将不会被执行。
      【解决方案9】:

      一个不需要子shell并且内置在bash中的选项

      (pushd SOME_PATH && run_stuff; popd)
      

      演示:

      $ pwd
      /home/abhijit
      $ pushd /tmp # directory changed
      $ pwd
      /tmp
      $ popd
      $ pwd
      /home/abhijit
      

      【讨论】:

      • Sahil 在下面提出了类似的建议。如果命令失败,它将不起作用。考虑pushd SOME_PATH &amp;&amp; run_stuff &amp;&amp; popd -- 如果 run_stuff 失败,则不会执行 popd。
      • 延迟回复,这取决于 bash 文件的设置。即使在命令失败后,Bash 也可以继续执行命令(与使用 && 不同),但可以在文件中使用 set -e 将其设置为不执行此操作,然后它将失败为 popd
      • 不过,我认为pushd "${SOME_PATH}" &amp;&amp; run_stuff; popd 比当前的答案更好,因为 pushd/popd 语义是专门为这种进入某个目录然后返回到原始目录的情况而设计的。跨度>
      • 定义为别名如何工作,我需要传递一个参数?
      • 我认为您需要编写一个 shell 脚本,将执行一系列命令的参数传递给该脚本,因为您不能在别名中间传递参数。如果您需要帮助编写该内容,您应该提出一个单独的问题并参考这个问题。一旦你有了 shell 脚本,你就可以编写一个别名来调用你的新脚本。
      【解决方案10】:

      只要把最后一个“&&”改成“;”无论命令失败还是成功,它都会 cd 返回:

      cd SOME_PATH && run_some_command ; cd -
      

      【讨论】:

        【解决方案11】:

        从当前目录提供脚本目录的完整路径以执行命令

        /root/server/user/home/bin/script.sh
        

        【讨论】:

        • 这根本不会改变工作目录 - 我认为您正在回答与所问问题不同的问题。
        • 来到这里是为了找到您回答的问题的答案。谢谢!大声笑
        猜你喜欢
        • 2016-01-09
        • 2013-08-01
        • 1970-01-01
        • 2019-09-30
        • 2014-11-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多