.bashrc中的shopt -s extdebug在脚本文件中不起作用 [英] shopt -s extdebug in .bashrc not working in script files

查看:210
本文介绍了.bashrc中的shopt -s extdebug在脚本文件中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个bash脚本(echoo.sh),目的是在执行该命令之前先回显该命令.我在.bashrc中获取此脚本(echoo.sh).但是对于使用bash shebang在脚本文件(tmp.sh)中运行的命令,它不会执行.以下是到目前为止的代码

I am writing a a bash script (echoo.sh) with the intention of echoing the command before it is executed. I source this script (echoo.sh) inside .bashrc. But it does not execute for commands run in script file(tmp.sh) with the bash shebang. Below is the code I have so far

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

当我打开一个外壳并运行任何命令时-它起作用.但是对于脚本文件中的内容则无效.

When I open a shell and run any command - It works. But for stuff in a script file it doesn't work.

一些其他文章:

  1. 我尝试在脚本文件(tmp.sh)中采购.bashrc文件-无效.
  2. 我在tmp.sh中获得了echoo.sh,并且有效.

所以,我正试图了解

  1. 如果我仅将.bashrc中的脚本作为脚本中运行的内容的源代码,为什么它不起作用?
  2. 为什么#2不能再尝试#1工作.

最后我该怎么做,以至于我不必在所有脚本文件中都包含echoo.sh来起作用.可以将我的脚本放在一个地方,并更改一些设置以使其在所有情况下都可以使用.

AND finally what can I do such that I don't have to source echoo.sh in all script files for this to work. Can source my script in one place and change some setting such that it works in all scenarios.

推荐答案

我在.bashrc内获取此脚本(echoo.sh).但是对于使用bash shebang在脚本文件(tmp.sh)中运行的命令,它不会执行

I source this script (echoo.sh) inside .bashrc. But it does not execute for commands run in script file(tmp.sh) with the bash shebang

是的,这不是因为您非交互地调用Shell!

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

Yes it won't because you are invoking the shell non-interactively!

The shell can be spawned either interactively or non-interactively. When bash is invoked as an interactive login shell it first reads and executes commands from the file /etc/profile, if that file exists. After reading that file, it looks for ~/.bash_profile, ~/.bash_login, and ~/.profile, in that order, and reads and executes commands from the first one that exists and is readable.

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

When an interactive shell that is not a login shell is started, bash reads and executes commands from ~/.bashrc, if that file exists.

运行带有解释器集的shell脚本时,它将打开一个新的非交互式子shell,该子shell在shell选项中未设置选项-i.

When you run a shell script with an interpreter set, it opens a new sub-shell that is non-interactive and does not have the option -i set in the shell options.

仔细查看~/.bashrc,您会发现一行:

Looking into ~/.bashrc closely you will find a line saying

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

表示您正在调用的脚本,例如考虑以下情况,使用-c选项显式生成非交互式外壳,而-x只是启用调试模式

which means in the script you are calling, e.g. consider the case below which am spawning a non-interactive shell explicitly using the -c option and -x is just to enable debug mode

bash -cx 'source ~/.bashrc'
+ source /home/foobaruser/.bashrc
++ [[ hxBc != *i* ]]
++ return

表示~/.bashrc的其余部分由于此保护而未执行.但是,在BASH_ENV环境变量所定义的情况下,这里有一个这样的选项可用于读取此类非交互情况下的启动文件.行为就像执行此行一样

which means the rest of the the ~/.bashrc was not executed because of this guard. But there is one such option to use here to read a start-up file for such non-interactive cases, as defined by BASH_ENV environment variable. The behavior is as if this line is executed

if [ -n "$BASH_ENV" ]; then . "$BASH_ENV"; fi

您可以定义文件并将其值传递给本地环境变量

You can define a file and pass its value to the local environment variable

echo 'var=10' > non_interactive_startup_file
BASH_ENV=non_interactive_startup_file bash -x script.sh

或者完全运行您的shell脚本,就像生成一个交互式非登录shell一样.使用-i标志运行脚本.重用上面的示例,并传递-i标志,现在将获取~/.bashrc文件.

Or altogether run your shell script as if an interactive non login shell is spawned. Run the script with an -i flag. Re-using the above example, with the -i flag passed now the ~/.bashrc file will be sourced.

bash -icx 'source ~/.bashrc'

将口译员在bash中设置为#!/bin/bash -i

因此,根据以上推论回答您的问题,

So to answer your questions from the above inferences,

  1. 如果我仅将.bashrc中的脚本作为脚本中运行的内容的源代码,为什么它不起作用?

这不是因为~/.bashrc不能从非交互启动的shell中获取.通过将-i传递到脚本即bash -i <script>

It won't because ~/.bashrc cannot be sourced from a shell that is launched non-interactively. By-pass it by passing -i to the script i.e. bash -i <script>

  1. 为什么#2不能再尝试#1工作.

因为您完全需要阅读~/.bashrc.在tmp.sh内部提供echoo.sh的源代码后,其所有外壳程序配置都将反映在tmp.sh

Because you are depending on reading up the ~/.bashrc at all here. When you did source the echoo.sh inside tmp.sh, all its shell configurations are reflected in the shell launched by tmp.sh

这篇关于.bashrc中的shopt -s extdebug在脚本文件中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆