Linux shopt-s extdebug in.bashrc在脚本文件中不工作

Linux shopt-s extdebug in.bashrc在脚本文件中不工作,linux,bash,shell,ubuntu-17.10,Linux,Bash,Shell,Ubuntu 17.10,我正在编写一个bash脚本(echoo.sh),目的是在执行命令之前对其进行响应。我将这个脚本(echoo.sh)源代码放在.bashrc中。但它不会对在带有bash-shebang的脚本文件(tmp.sh)中运行的命令执行。下面是我到目前为止的代码 echoo.sh #!/usr/bin/env bash shopt -s extdebug; get_hacked () { [ -n "$COMP_LINE" ] && return # not needed for

我正在编写一个bash脚本(echoo.sh),目的是在执行命令之前对其进行响应。我将这个脚本(echoo.sh)源代码放在.bashrc中。但它不会对在带有bash-shebang的脚本文件(tmp.sh)中运行的命令执行。下面是我到目前为止的代码

echoo.sh

#!/usr/bin/env bash
shopt -s extdebug; get_hacked () {
    [ -n "$COMP_LINE" ] && return  # not needed for completion
    [ "$BASH_COMMAND" = "$PROMPT_COMMAND" ] && return # not needed for prompt
    local this_command=$BASH_COMMAND;
    echo $this_command;
};
trap 'get_hacked' DEBUG
当我打开一个shell并运行任何命令时,它都会工作。但是对于脚本文件中的内容,它不起作用

一些进一步的尝试:

  • 我尝试在脚本文件(tmp.sh)中寻找.bashrc文件,但没有成功
  • 我在tmp.sh中找到了echoo.sh,它成功了
  • 所以,我试图理解

  • 如果我只是在.bashrc中为脚本中运行的东西提供脚本源代码,为什么它不起作用
  • 为什么当第二次尝试时,第1次尝试不起作用呢
  • 最后,我可以做些什么,这样我就不必在所有脚本文件中都源代码echoo.sh,这样才能工作。您可以在一个地方获取脚本的源代码,并更改一些设置,使其在所有场景中都能工作

    我将这个脚本(echoo.sh)源代码放在.bashrc中。但它不会对在脚本文件(tmp.sh)中使用bash-shebang运行的命令执行

    是的,不会,因为您正在以非交互方式调用shell! 可以以交互方式或非交互方式生成shell。当作为交互式登录shell调用
    bash
    时,它首先读取并执行文件
    /etc/profile
    中的命令(如果该文件存在)。读取该文件后,它将按顺序查找
    ~/.bash\u profile
    ~/.bash\u login
    ~/.profile
    ,并从第一个存在且可读的文件读取和执行命令

    启动非登录shell的交互式shell时,
    bash
    读取并执行
    ~/.bashrc
    中的命令(如果该文件存在)

    当您使用解释器集运行shell脚本时,它会打开一个新的非交互式子shell,并且在shell选项中没有设置选项
    -i

    仔细查看
    ~/.bashrc
    ,你会发现一句话

    # If not running interactively, don't do anything
    [[ "$-" != *i* ]] && return
    

    这意味着在您正在调用的脚本中,例如,考虑下面的情况,即生成一个非交互式shell,明确使用“代码> -c>代码>选项和<代码> -x>代码>只允许调试模式

    bash -cx 'source ~/.bashrc'
    + source /home/foobaruser/.bashrc
    ++ [[ hxBc != *i* ]]
    ++ return
    
    这意味着
    ~/.bashrc
    的其余部分并没有因为这个保护而执行。但是这里有一个这样的选项用于读取此类非交互案例的启动文件,如
    BASH_ENV
    环境变量所定义。行为就像执行了这一行一样

    if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi
    
    可以定义文件并将其值传递给本地环境变量

    echo 'var=10' > non_interactive_startup_file
    BASH_ENV=non_interactive_startup_file bash -x script.sh
    
    或者完全运行shell脚本,就像生成了一个交互式非登录shell一样。使用
    -i
    标志运行脚本。重新使用上面的示例,现在通过了
    -i
    标志,将获取
    ~/.bashrc
    文件

    bash -icx 'source ~/.bashrc'
    
    您还可以在将解释器she bang in
    bash
    设置为
    #时设置此选项/bin/bash-i

    因此,为了回答您从上述推论中提出的问题

  • 如果我只是在.bashrc中为脚本中运行的东西提供脚本源代码,为什么它不起作用
  • 不会,因为不能从非交互启动的shell中获取
    ~/.bashrc
    。通过将
    -i
    传递到脚本,即
    bash-i

  • 为什么当第二次尝试时,第1次尝试不起作用呢

  • 因为您需要在这里阅读
    ~/.bashrc
    。当您在
    tmp.sh
    内部找到
    echoo.sh
    时,它的所有shell配置都反映在
    tmp.sh

    启动的shell中,shell启动时读取的一系列文件是否仅适用于交互式shell?是否有交互和非交互Shell都可以读取的文件?@SamThomas:没有,这两种Shell之间没有通用的启动文件。您可以使用我在答案中建议的
    BASH_ENV
    选项。在一个文件中定义所有函数/变量,并将其完整路径传递给变量,当您调用脚本时,我尝试了这一点,并使脚本适用于非交互式shell。但是,你能有一个好主意吗?它的工作原理非常不同。