Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macos 如何隐式运行shell脚本?_Macos_Bash_Shell_Scripting - Fatal编程技术网

Macos 如何隐式运行shell脚本?

Macos 如何隐式运行shell脚本?,macos,bash,shell,scripting,Macos,Bash,Shell,Scripting,我制作了一个shell脚本作为终端命令运行,但是它里面的cd命令无效,因此我想用source运行它,以便cd命令生效 脚本名称:“project.sh” 我将此文件添加到/usr/local/bin,通过chmod+x project.sh使其可执行,运行正常,但cd命令不起作用 我知道它是在一个子进程中运行的,因此在结束时,终端返回到起始目录,不会对project.sh中的cd命令产生任何影响 在中介绍的解决方案不适用于我,因为它们要求我运行source,如果我想将其用作Bash命令,这是不可

我制作了一个shell脚本作为终端命令运行,但是它里面的
cd
命令无效,因此我想用
source
运行它,以便
cd
命令生效

脚本名称:
“project.sh”

我将此文件添加到
/usr/local/bin
,通过
chmod+x project.sh
使其可执行,运行正常,但
cd
命令不起作用

我知道它是在一个子进程中运行的,因此在结束时,终端返回到起始目录,不会对
project.sh
中的
cd
命令产生任何影响


在中介绍的解决方案不适用于我,因为它们要求我运行
source
,如果我想将其用作Bash命令,这是不可能的。

您使用
source
命令:

source /usr/local/bin/project.sh
无法通过键入始终在子流程中运行脚本的脚本名称自动实现这一点。如果您不想全部键入这些内容,可以在
.bashrc
中创建一个别名来简化它:

alias project='source /usr/local/bin/project.sh'
然后键入
project
将转换为完整的命令。

当然,
source
是一个Bash命令-它使用
source
内置命令在当前shell的上下文中而不是在子进程中运行脚本,从而允许
中的命令更改当前shell的环境,例如工作目录(使用
cd
)。
使用
源代码
,或其别名
,最终是实现这一目标的唯一途径

如果您的意图是不必使用
源代码显式调用
,那么您有两个选项,这两个选项在Bash配置文件
~/.Bash\u配置文件
(因为您使用的是OS X;在Linux上,请使用
~/.bashrc
[1]):

我将假定您的脚本是
/path/to/foo
,并且您希望以
foo
的形式调用它:

  • 选项1:定义一个别名
    别名foo='source”/path/to/foo'
  • 选项2:定义一个函数
    foo(){source”/path/to/foo;}
别名和函数都在当前shell中执行,允许您有效地将
源调用隐藏在单个命令后面;别名通常更容易定义,但函数提供了更大的灵活性

由于Bash概要文件中定义的别名/函数本身是隐式源代码,
/path/to/foo
中的命令将影响交互式shell的环境

注意
foo
的任一定义仅在交互式shell中可用(那些(自动)源代码
~/.bash\u配置文件
)。 要使
foo
在非源代码脚本中工作,还需要额外的步骤,但在这一点上,您应该问问自己,您是否因为没有明确说明
/path/to/foo
正在获得源代码而使事情变得模糊


如果您正在编写一个脚本,该脚本必须源代码分发给其他人:

  • 在安装脚本时,在用户的shell概要文件/初始化文件(如上所述)中安装sourcing命令

    • 如果没有安装过程(通常也支持按需安装),请为脚本实现命令行选项,例如执行此按需安装的
      i
      --install
      )。
      最好还实施卸载选项
  • 无论哪种方式,都要将逻辑构建到脚本中,以便在没有源代码的情况下运行时拒绝运行,并让错误消息包含有关如何安装源代码的说明

    • 有关如何检测来源,请参阅
上述内容的一个真实实现——尽管由于是多shell而更加复杂——是我的;源代码


[1] 在OS X上,Terminal.app启动的Bash实例是登录shell,这意味着启动时自动获取的唯一(用户特定)文件是
~/.Bash\u profile

相比之下,在大多数Linux系统上,Bash实例是非登录shell,其中只有
~/.bashrc
是自动来源的。

虽然通常的做法是从一个人的
~/.bashrc
配置文件中获取
~/.bashrc
,但这必须手动配置,因此不能盲目依赖。

只需定义一个函数(例如在你的
.bashrc
中)。如果你要求的是可能的,那将是一场噩梦(作为最终用户):现在,我可以确信,我运行的任何非shell内置、函数或别名的命令都将保留shell的状态(工作目录、变量等)。你要求的是一种违反承诺的方式:它不能,也不应该这样做。因此:这是不可能的,而且出于充分的理由,这是故意不可能的……有一些命令可以自动编辑用户的点文件,例如rvm,但要以一种行为良好(进行备份等)并充分记录的方式来做这件事需要做大量的工作(因此用户了解他们需要重新启动打开的shell或从中重新获取点文件的源代码,等等).alias是一种方法,但有没有任何方法可以让我不必执行该过程?是否可以在默认情况下将脚本设置为源代码?或者我可以通过某种方式将其添加到脚本中,以便脚本以源代码的形式运行?我想将其设置为一个包,以便其他人可以简单地运行它,并且所有这些参数都可以从脚本本身设置。您看到我在哪里说过了吗ronpatel:麻烦但唯一可行的解决方案是编写一种安装机制,将寻源命令(通过别名或函数)添加到用户的shell中