标准终端命令行和 bash 脚本的环境有何不同?

Pet*_*r.O 6 command-line bash scripts

我知道终端命令行的环境和 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 release i486-pc-linux-gnu(在终端和脚本中)

CLI 和脚本之间的“shopt”区别:

    CLI   Script  
    on     off    checkwinsize    
    on     off    expand_aliases  
    on     off    extglob         
    on     off    histappend      
    off    on     hostcomplete    
Run Code Online (Sandbox Code Playgroud)

造成这种差异的原因是什么?

即使一些升级将使它在脚本中工作......
我正在努力找出什么为什么,所以在未来,我会知道要注意什么。


这里有 3 种bash方法来去除前导“0”。(我第一次问这个问题时只知道一个)

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  
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 7

假设您在脚本和终端中使用相同的 shell,主要区别在于它~/.bashrc由交互式 shell 读取,而不是由脚本解释 shell 读取。原因是脚本通常具有一定的可移植性,因此您不想依赖于用户的 shell 自定义。

典型.bashrc文件中的许多内容无论如何都只适用于命令行(提示设置、键绑定)。有些,比如函数定义,在脚本中也有意义;通常,您会将它们放入一个单独的文件中,并从~/.bashrc和 脚本中获取它。有时您需要一些 shell 选项用于交互使用而不是在脚本中,因为它们会导致代码更短(在命令行上很好)但更神秘或更不便携(在脚本中不好)。bash 有一些不同的功能,例如历史扩展(!!等)仅在交互式 shell 中默认启用。

这里您使用的是+(…)构造,它是一个 ksh 扩展的通配模式。Bash 默认不启用它们(为了向后兼容),但您可以使用shopt -s extglob. 显然你在你的~/.bashrc.

您可以放入shopt -s extglob脚本,或使用可移植的方式0从变量中截断前导s,例如

var=${var#${var%%[!0]*}}
Run Code Online (Sandbox Code Playgroud)


loe*_*org 2

你的问题不能很笼统地回答。不过有些评论。在我的 bash 版本(3.1.17(1)-release)上,即使从命令行运行,您的命令也没有所需的输出;与 zsh 相同。所以想必你的命令有些可疑。我不知道“##+(0)”应该完成什么,但“#0”成功地删除了一个前导零。展示了一种删除任意数量的零的方法。

如果命令行上的行为和脚本中的行为确实存在差异,那么该脚本很可能使用不同的解释器(不同的 bash 版本,bash 而不是 zsh)或不同的 shell 选项(尝试运行shopt)。后一个差异可能是交互式 shell 来源的结果$HOME/.bashrc,而$HOME/.profile脚本通常不是。这不应该影响环境变量,因为它们如果导出就会被继承,但它应该影响 shell 选项,这些选项需要在每个 shell 中设置。