.bashrc中的shopt -s extdebug无法在脚本文件中运行

时间:2018-02-06 08:17:51

标签: linux bash shell ubuntu-17.10

我正在编写一个bash脚本(echoo.sh),目的是在执行命令之前回显该命令。我在.bashrc中找到了这个脚本(echoo.sh)。但是对于使用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并运行任何命令时 - 它有效。但对于脚本文件中的内容,它无法正常工作。

进一步的尝试:

  1. 我尝试在脚本文件(tmp.sh)中获取.bashrc文件 - 没有用。
  2. 我在tmp.sh中找到了echoo.sh,但它确实有效。
  3. 所以,我正在努力理解

    1. 如果我只是在.bashrc中获取脚本中运行的东西,为什么它不起作用呢?
    2. 为什么#2没有进一步尝试#1工作。
    3. 最后我能做些什么,以至于我不必在所有脚本文件中提供echoo.sh,以便工作。可以在一个地方获取我的脚本并更改一些设置,使其适用于所有场景。

1 个答案:

答案 0 :(得分:2)

  

我在.bashrc中找到了这个脚本(echoo.sh)。但是对于使用bash shebang

在脚本文件(tmp.sh)中运行的命令,它不会执行

是的,它赢了,因为你是以非交互方式调用shell!

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

当启动不是登录shell的交互式shell时,如果该文件存在,bash将从~/.bashrc读取并执行命令。

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

密切关注~/.bashrc你会发现一句话

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

表示您正在调用的脚本,例如考虑下面的情况,它使用-c选项显式生成非交互式shell,而-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'

您还可以在bash#!/bin/bash -i

中设置解释器时设置此选项

所以从上述推论回答你的问题,

  
      
  1. 如果我只是在.bashrc中获取脚本中运行的东西,为什么它不起作用呢?
  2.   

它不会因为~/.bashrc无法从非交互式启动的shell中获取。通过将-i传递给脚本即bash -i <script>

来绕过它
  
      
  1. 为什么#2没有进一步尝试#1工作。
  2.   

因为您完全依赖于阅读~/.bashrc。当您确实在echoo.sh内部tmp.sh获取内容时,其所有shell配置都会反映在tmp.sh

启动的shell中