我知道终端命令行的环境和 bash 脚本中的环境有一些不同,但我不知道那个区别是什么......
这是最终导致我提出这个问题的示例;它可能会消除一些差异。
我正在尝试使用此命令从数字中去除前导 '0'。
var="000123"; var="${var##+(0)}" ; echo $var
当我从终端的命令行运行此命令时,我得到: 123
但是,当我从脚本中运行它时,它不起作用;我得到: 000123
我正在使用 Ubuntu 10.04,并使用 sam 结果尝试了以下所有操作:
- GNOME 终端 2.30.2
- 控制台 2.4.5
- #!/bin/bash
- #!/bin/sh
我的 bash 版本 4 1 5 1 发行版 i486-pc-linux-gnu(在终端和脚本中)
CLI 和脚本之间的“shopt”差异:
CLI Script
on off checkwinsize
on off expand_aliases
on off extglob
on off histappend
off on hostcomplete
是什么导致了这种差异?
即使一些升级将使它在脚本中工作......
我试图找出什么和为什么,所以在未来,我会知道要注意什么。
以下是去除前导 '0' 的 3种bash方法。(我第一次问这个问题时只知道一个)
var=0001230; var="$[10#$var]"; echo $var # fastest= 1.00 integers only
var=0001230; var="${var##+(0)}"; echo $var # slower x 1.25 works with strings, but requires shopt -s extglob
var=0001230; var="${var#${var%%[!0]*}}"; echo $var # slower x 1.61 works with strings
假设您在脚本和终端中使用相同的 shell,主要区别在于
~/.bashrc
交互式 shell 可以读取,但脚本解释 shell 不能读取。原因是脚本通常具有一定的可移植性,因此您不想依赖用户的 shell 自定义。无论如何,典型文件中的许多内容
.bashrc
仅适用于命令行(提示设置、键绑定)。有些,比如函数定义,在脚本中也有意义;通常,您会将它们放入一个单独的文件中,并从~/.bashrc
脚本和脚本中获取它。有时您需要一些用于交互使用的 shell 选项,但不是在脚本中,因为它们会导致代码更短(在命令行上很好)但更神秘或更不便携(在脚本中不好)代码。bash 有一些不同的做法,例如历史扩展(!!
等)默认情况下仅在交互式 shell 中启用。在这里,您使用的是
+(…)
构造,它是 ksh 扩展的通配模式。Bash 默认情况下不启用它们(为了向后兼容),但您可以使用shopt -s extglob
. 显然你的~/.bashrc
.您可以放入
shopt -s extglob
脚本,或使用可移植的方式0
从变量中截断前导,例如你的问题不能很笼统地回答。不过有些评论。在我的 bash 版本(3.1.17(1)-release)上,即使从命令行运行,您的命令也没有所需的输出;与 zsh 相同。因此,您的命令可能有些可疑。我不知道“##+(0)”应该完成什么,但是“#0”成功地删除了一个前导零。这显示了一种删除任意数量的零的方法。
如果命令行上的行为和脚本的行为之间确实存在差异,那么脚本很可能使用不同的解释器(不同的 bash 版本,bash 而不是 zsh)或不同的 shell 选项(尝试运行
shopt
)。后一种差异可能是您的交互式外壳采购的结果,$HOME/.bashrc
而$HOME/.profile
脚本通常不会。这不应该影响环境变量,因为它们在导出时会被继承,但它应该会影响 shell 选项,这些选项需要在每个 shell 中设置。