我正在读理查德·布鲁姆和克里斯汀·布雷斯纳汉的《Linux命令行和shell 脚本圣经》.在处理不同的特殊变量(如$#$@)一节中,他们指出,尽管$#包含最终参数的索引,但它不能用于缩短访问最终参数的路径,例如:${$#}.相反,我们应该使用${!#}.对于why,没有给出太多的解释.情况就是这样,只是事实如此.

这一切都很好,我会记住我是否应该go 做这样的事情--但bash的机制(或者甚至只是超出介绍性文本范围的功能)中是否隐藏着一些更深层次的原因来解释为什么${$#}不起作用?我花了一些时间在互联网上寻找答案,但没有发现太多.Bash的手册页提到了这一点,但对我来说没有任何意义.

推荐答案

为什么我们不能使用${$#}来获取传递给shell 脚本的最后一个参数?

我们不能使用${$#}来获取最后一个参数,因为变量展开不是递归的,{ }的内容只被shell 解析一次.我们不能使用它,因为它从未实施过.我认为这里真的没有太多解释,只是说是这样的.

没有太多的解释是为什么会这样,只是它是如此.

虽然我们不能在物理学中解释为什么,但你可以认为我们可以在编程中解释为什么.对于"为什么",唯一的答案是"因为它是以这种方式被创造出来的".写(第一个)shell的人是这样写的,它得到standardized ,现在所有的标准shell 都是这样工作的.

很可能是这样写的,因为它很容易做到.我想这是我们能得到的最好的解释了.

如果我确实 echo 了${$#},我会得到一个随机数字(当我try 它时,我得到了5138).这个数字有任何意义吗?

  • echo $$表示当前shell 进程的PID.
  • echo ${$}还给出了当前shell 进程的PID.
  • 如果为${var#string},则从展开var的开始中删除string
    • 例如,a=1234; echo ${a#12}1234的开头删除12,得到34.
  • ${$#}扩展到当前的pid,如$$,然后#删除."nothing"从变量的开始,所以它是相同的$$.

https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html章第${parameter#word}

记住使用shellcheck https://www.shellcheck.net/判断您的脚本.也要判断https://mywiki.wooledge.org/BashFAQ.

Linux相关问答推荐

awk:try 将时间戳字符串转换为unix纪元时间

并行函数的最后一个实例的状态

X86_64程序集中的分段故障:系统调用问题

从 MariaDB 连接到 Oracle 时出现错误消息libsqora.so.11.1:找不到文件

sed + 从没有额外空格的文本中删除单词

如何比较 2 个文件并将第二个文件的所有行打印到输出文件 awk

sed:用空格替换

中的换行符

将特定列转换为行

为什么 8 位字符串文字可以包含多字节字符,而 char 向量不能?

anon 对 pmap 意味着什么?

用于判断进程是否正在运行并对结果采取行动的 Linux 脚本

我需要 -D_REENTRANT 和 -pthreads 吗?

如何在 Linux 中使用命令行将 PDF 转换为 JPG?

zsh/bash 上不区分大小写的 Glob

如何链接到 GCC 中特定版本的共享库

如何让 cron 每N分钟运行一次,其中 n % 5 == 1?

Anaconda 安装后,conda 命令失败并显示ImportError: no module named conda.cli

我可以使用 awk 将所有小写字母转换为大写吗?

查找和基本名称不能很好地播放

linux脚本杀死java进程