2

我正在编写一个 bash 脚本(echo.sh),目的是在执行命令之前对其进行回显。我在 .bashrc 中获取此脚本 (echo.sh)。但是对于使用 bash shebang 在脚本文件(tmp.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

当我打开外壳并运行任何命令时 - 它可以工作。但是对于脚本文件中的内容,它不起作用。

一些进一步的尝试:

  1. 我尝试在脚本文件 (tmp.sh) 中获取 .bashrc 文件 - 没有用。
  2. 我在 tmp.sh 中获取了 echoo.sh 并且它起作用了。

所以,我试图理解

  1. 如果我只是在 .bashrc 中为在脚本中运行的东西提供脚本,为什么它不起作用?
  2. 当#2 做时,为什么不进一步尝试#1 工作。

最后,我能做些什么,这样我就不必在所有脚本文件中获取 echoo.sh 即可。可以在一个地方获取我的脚本并更改一些设置,使其适用于所有场景。

4

1 回答 1

3

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

是的,它不会因为您以非交互方式调用 shell!

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

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

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

~/.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您也可以在将解释器 she-bang 设置为时设置此选项#!/bin/bash -i

因此,要从上述推论中回答您的问题,

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

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

  1. 当#2 做时,为什么不进一步尝试#1 工作。

因为你完全依赖于阅读~/.bashrc这里。当您对echoo.shinside进行 source 时tmp.sh,它​​的所有 shell 配置都会反映在由tmp.sh

于 2018-02-06T08:47:30.903 回答