我正在编写一个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并运行任何命令时 - 它有效。但对于脚本文件中的内容,它无法正常工作。
进一步的尝试:
所以,我正在努力理解
最后我能做些什么,以至于我不必在所有脚本文件中提供echoo.sh,以便工作。可以在一个地方获取我的脚本并更改一些设置,使其适用于所有场景。
答案 0 :(得分:2)
我在.bashrc中找到了这个脚本(echoo.sh)。但是对于使用bash shebang
在脚本文件(tmp.sh)中运行的命令,它不会执行
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
所以从上述推论回答你的问题,
- 如果我只是在.bashrc中获取脚本中运行的东西,为什么它不起作用呢?
醇>
它不会因为~/.bashrc
无法从非交互式启动的shell中获取。通过将-i
传递给脚本即bash -i <script>
- 为什么#2没有进一步尝试#1工作。
醇>
因为您完全依赖于阅读~/.bashrc
。当您确实在echoo.sh
内部tmp.sh
获取内容时,其所有shell配置都会反映在tmp.sh