为什么 'echo $0' 对两个不同的终端给出不同的结果?

Cod*_*lue 17 bash ubuntu terminal gnome-terminal

我用开在Ubuntu终端Ctrl+ Alt+ T,并通过进入到一个目录,然后右击并选择“打开在终端”不同的终端。

echo $0在这两种情况下都做了。

在第一种情况下:

$ echo $0
-bash
Run Code Online (Sandbox Code Playgroud)

在第二种情况下:

$ echo $0
/bin/bash
Run Code Online (Sandbox Code Playgroud)

为什么会有这种差异?

Rad*_*anu 16

如果echo $0命令的输出是,-bash则意味着它 bash被作为登录 shell 调用。如果输出仅为bash,则您处于非登录 shell 中。

man bash 在第 126 行的某处说:

A  login shell is one whose first character of argument zero is a -, or 
one started with the --login option.
Run Code Online (Sandbox Code Playgroud)

在此处查看更多信息:登录外壳和非登录外壳之间的区别?.

现在,要解释为什么会/bin/bash出现第二种情况,我可以说程序(在您的情况下是文件管理器,可能是 nautilus)或脚本可以将其自身更改$0为其他内容。例如,看看$0我的终端(一直在同一个终端)中发生了什么:

在此处输入图片说明


X T*_*ian 13

不同之处在于这些开始的方式。bash 将根据它的 argv[0] 进行不同的初始化(读取不同的启动脚本)。如果字符串以连字符开头,--bash那么它会作为一个登录shell,如果不是,它将作为一个交互式shell中运行。它也可以作为非交互式 shell 运行(即在 shell 脚本中)。

要了解更多信息,最好阅读手册,man bashINVOCATION 部分。


Mar*_*ick 9

shell 在您登录时启动,但它也由诸如make、运行 shell 脚本、键入:shtovi或创建新终端窗口时启动。

最初,shell 在~/.profile您登录或运行时读入su。这个脚本会做一些事情,比如宣布你是否有新电子邮件,自定义你的擦除和删除字符,以及设置和导出 TERM 和 PATH 变量。在几乎任何其他上下文中启动时,shell 都不会读取~/.profile,因为执行大多数这些操作都是多余的。您应该将所有重要的 shell 变量导出到新的 shell。

shell 知道是否读入的方法~/.profile是检查 的第一个字符argv[0],也$0就是'-'.

从 开始csh,引入了别名。别名未在环境中导出。csh旨在读取两个不同的初始化脚本。~/.login仅在用户登录时读取,执行此操作的提示argv[0]是以'-'. ~/.cshrc每次启动外壳时都会读取。在一般情况下,一个放置在别名~/.cshrc和其他一切~/.logincsh也支持~/.logout,在大多数情况下只是清除屏幕并运行fortune

其他外壳采用了这些相同的功能。ksh会读~/.kshrcbash会读的~/.bashrc,而这些都是在那里你把你的别名定义。

因此,长话短说,生成 shell 的应用程序可以决定它应该是“登录 shell”(在这种情况下'-'是开头的登录 shell)还是常规 shell。在大多数情况下,将要交互的 shell 作为登录 shell 启动,而 shell 仅用于运行一些命令,作为参数或从脚本中运行,然后退出是常规 shell。

但这完全取决于启动 shell 的应用程序的心血来潮。