我有一个常用命令,需要从特定的目录中调用。该程序只有一个可执行文件位于/bin中,当前工作目录对于正确运行它非常重要。该脚本会影响在其所在目录中的文件。
现在,我还有一个自定义的shell脚本,在一个目录中进行一些操作,但我需要调用上述命令,就像它在另一个目录中一样。
如何在shell脚本中实现这个功能?
我有一个常用命令,需要从特定的目录中调用。该程序只有一个可执行文件位于/bin中,当前工作目录对于正确运行它非常重要。该脚本会影响在其所在目录中的文件。
现在,我还有一个自定义的shell脚本,在一个目录中进行一些操作,但我需要调用上述命令,就像它在另一个目录中一样。
如何在shell脚本中实现这个功能?
在子shell中使用cd
命令;使用这种类型的子shell的简写方式是使用圆括号。
(cd wherever; mycommand ...)
话虽如此,如果您的命令需要特定的环境,则应确保该环境而不是将责任放在可能想要使用它的任何东西上(除非它是在完全定义良好的更大系统的特定情况下使用的内部命令,以便任何调用者已经需要确保其所需的环境)。通常这将是某种shell脚本包装器。
(cd /path/to/your/special/place;/bin/your-special-command ARGS)
你可以使用内置命令 cd
或 pushd
和 popd
来实现这个目的。例如:
# do something with /etc as the working directory
cd /etc
:
# do something with /tmp as the working directory
cd /tmp
:
您可以像使用任何其他命令一样使用内置命令,并且在脚本中可以随意更改目录上下文。
cd -
可以返回上一个目录。尽管如此,(a) pushd
和 popd
确实是为交互式使用而设计的,(b) 在复杂的子系统中,不能总是安全地假设您可以返回原来的目录,特别是当它们可能在内部使用限制权限时(请参见 https://dev59.com/GGPVa4cB1Zd3GeqP8b2p)。 - geekosaurpopd
。 - connorbode:
符号是什么意思? - Vadim Kotovman bash
的相关部分中,写着:: [arguments]
无效果; 命令除了扩展参数和执行任何指定的重定向外,什么也不做。返回状态为零。 - boycycurrent_dir=$PWD;cd /path/to/your/command/dir;special command ARGS;cd $current_dir;
current_dir
设置为你的pwd
cd
到你需要运行命令的位置cd
回到我们的current_dir
变量中pushd && cd /path/to/your/command/dir && special command ARGS && popd
感谢 @apieceofbart 和 @Konstantin 的支持
pushd && YOUR COMMAND && pulld
这个命令。 - apieceofbartpushd /path/to/your/command/dir && 特殊命令参数 && popd
- M.Adam您也可以使用env
命令来实现相同的功能,而无需额外的shell:
env --chdir=/whatever/path -S whatever_command -some -option and any other arguments
其中whatever_command
是要执行的命令或脚本以及所有相关选项和参数。所有这些必须遵循env
命令的-S
选项。
当前工作目录只在execvp()
系统调用中更改,因此最终它将返回到其原始值。
env
是GNU coreutils
软件包的一部分,可以在这里找到其手册页面以获取更多详细信息。
实际上,您还可以使用env
来仅针对特定执行操作环境变量和信号处理。
迟到回答这个问题,我必须指出:这里没有回答到ShellCheck SC2164!!
解释:如果在执行破坏性命令之前遇到拼写错误的路径:
( cd /wrong/path ; rm -fR * )
cd
命令会失败,然后后续命令会摧毁当前目录中的所有内容!!
因此,正确的命令是
( cd /path/to/wherever || exit; mycommand ... )
或者
( cd /path/to/wherever && mycommand ... )
简单实用的小技巧:
这将把shell目录更改为~/project
function mymake() {
cd ~/project && make $1
}
这不会
function mymake() {
(cd ~/project && make $1)
}
运行
mymake something
function mymake() { ( cd ~/project && make $1 ) }
,以避免括号被误认为是花括号的简单错误。 - Edwin Buck