【问题标题】:In UNIX shell scripting: What does $! expand to?在 UNIX shell 脚本中:$!扩大到?
【发布时间】:2009-11-04 10:35:26
【问题描述】:

$ 是什么意思!在 shell 或 shell 脚本中?我正在尝试理解具有以下内容的脚本。

local@usr> a=1
local@usr> echo $a
1
local@usr> echo $!a
a

它正在将变量打印回来。都是为了这个吗?我们还有哪些其他 $x 选项?我知道的很少有 $$、$*、$?。如果有人能给我指出一个好的来源,那将会很有帮助。顺便说一句,这是在 Sun OS 5.8、KSH 中。

【问题讨论】:

  • 我发现令人惊讶的是,公认的答案是围绕对 Bash 手册的引用构建的,因为您指定了 ksh (Sun OS 5.8)。
  • 是的。那时,我没有看到 BASH 和 KSH 之间的区别。

标签: unix shell ksh


【解决方案1】:

Bash manual 中描述了各种 $… 变量。根据手册$! 扩展为在后台启动的最后一个进程的PID。见:

$ echo "Foo"
Foo
$ echo $!

$ true&
[1] 67064
$ echo $!
67064
[1]+  Done                    true

ksh 中似乎也是如此。

【讨论】:

  • 这是什么意思?我试过了,我不明白它是什么? usr>回声$! 17893 usr> 假 usr> 回声 $! 17893
  • 大师,试试这个:sleep 120 & ;回声 $1 ; ps -ef | grep $!
  • 它是最后一个 *background 作业的 PID - 在您运行后台作业之前它不会改变。
  • @paxdiablo。伟大的。现在,我明白了。
【解决方案2】:

来自我系统上的 ksh 手册页:

${!vname} 扩展为 vname 引用的变量的名称。这个 将是 vname ,除非 vname 是名称引用。

【讨论】:

  • 也许是一个例子?扩展使我感到困惑。 :(
  • man ksh 会告诉你,这里的答案太多了。
  • 这种形式称为间接。 a=1; b=a; echo ${!b} 导致打印“1”。
  • shell 扩展 ${!var} 不是所要求的。是$!
【解决方案3】:

对于您要询问的 shell,ksh,请使用 the ksh manual,并阅读以下内容:

参数替换
参数是一个标识符,一个或多个数字,或任何 字符 *、@、#、?、-、$ 和 !。

很明显,这些是可接受的选项 $*、$@、$#、$?、$-、$$ 和 $!。
未来可能会包含更多内容。


对于参数$!,来自手册:

“!”最后调用的后台命令的进程号。

如果你启动一个后台进程,比如sleep 60 &,那么这个进程会有一个进程号,参数$!将打印其编号。

$ sleep 60 &
[1] 12329
$ echo "$!"
12329

如果执行中没有后台进程(如 shell 启动时),则扩展为空。它有一个空值。

$ ksh -c 'echo $!'

如果有后台进程,则扩展为该进程的PID:

$  ksh -c 'sleep 30 & echo $!'
42586

这就是echo $!a 扩展为a 的原因。这是因为没有PID要报告:

$  ksh -c 'echo $!a'
a

其他 shell 可能有不同(通常非常相似)的扩展列表(一个只有一个 $ 和一个下一个字符的参数)。
例如,bash 将此*@#?-$!0_ 识别为“特殊参数”。在the Bash manual 中搜索标题“3.​​4.2 特殊参数”。

特殊参数
shell 专门处理几个参数。

【讨论】:

    【解决方案4】:

    它给出了最后一个后台作业或后台函数的进程ID 请通过下面的这个链接

    http://www.well.ox.ac.uk/~johnb/comp/unix/ksh.html#specvar
    

    【讨论】:

      【解决方案5】:

      !是 unix 中的引用运算符,尽管它不是用该名称调用的。

      它总是指一个母进程。尝试输入:!在 vi 中,它会将您带到命令提示符,您可以照常执行命令,直到退出命令。

      !在 SQLPLUS 中也从命令提示符执行命令。在 sqlplus 中试试这个

      SQL> !ls --- 这给出了当前目录中的文件列表。

      $! - 显然给出了当前/最新进程的进程ID。

      【讨论】:

      • -1 用于命名完全不相关的语言或环境中的一百万个其他用途中的 3 个。 $! 在 shell 中只有一个含义(如果之前没有学过,这远非显而易见)。