【问题标题】:bash aliases set in while loop not persisting在while循环中设置的bash别名不持久
【发布时间】:2019-05-27 13:59:24
【问题描述】:

好的,我已经编写了一个 shell 脚本来读取格式为:

快捷方式1 /path/to/directory1
快捷方式2 /path/to/directory2

它应该读取文件并构建别名,以便将快捷方式1 cd's me 输入映射目录。问题是,循环中设置的任何别名都不会在脚本之外持续存在。

首先我尝试运行脚本。

。 ./build_shortcuts.sh "~/.shortcuts"

文件 ~/.shortcuts 包含在哪里

dl ~/下载
音乐/音乐
dtop ~/桌面

这不起作用。然后我尝试在循环之外设置一些别名。如别名 hello='world';别名世界='hellob'。我重新运行脚本,输入 alias 以获取别名列表,它确实包含 hello 和 world 作为别名,但没有包含在循环中设置的任何别名。

然后我想也许循环根本没有设置它们,所以我在脚本中添加了别名作为最终命令,这样它就会在最后打印出别名;在这种情况下,它确实包含了别名,但它们仍然没有在我的会话中持续存在。

build_shortcuts.sh

script="$(cat $@ | sed -r -e 's/#[A-Za-z0-9 ]*$//' -e '/^\s+/s/^\s+//' -e '/^\s*$/d' -)"
# strip comments, entry level indentation & empty lines (in that order) from filestream

echo "${script}" | while read shortcut; do
    cut=$(echo  "${shortcut}" | awk '{         print $1 }')
    dest=$(echo "${shortcut}" | awk '{ $1=nil; print $0 }')
    dest="${dest:1}" # trim leading whitespace character

    alias "${cut}" &>/dev/null

    if [ $? = 0 ]; then
        echo "Warning: shortcut \"${cut}\" already exists" >&2
        continue # by default, skip overwriting shortcuts
    fi

    echo alias ${cut}="'cd ${dest}'"
    alias "${cut}"="'cd ${dest}'"
done

我希望脚本内循环中设置的别名存在于脚本之外。目前他们没有。

我在 Arch linux 上运行“GNU bash,版本 5.0.7(1)-release (x86_64-pc-linux-gnu)”。

【问题讨论】:

  • 请注意,~ 在引号内时不会扩展。

标签: bash sh alias


【解决方案1】:

来自the Bash manual page管道部分):

管道中的每个命令都作为单独的进程执行(即,在子 shell 中)

由于循环是作为管道的一部分完成的,因此它将是一个子shell,并且您在子shell中执行的别名命令只会为该子shell设置。

一种可能的解决方法是将别名保存到一个列表中,然后在第二个循环中执行实际的alias 命令,该循环不是管道或子shell 的一部分。

【讨论】:

    【解决方案2】:

    你的脚本可以精简一点:它不需要调用这么多外部工具。

    while read -r cut dest; do
        if alias "${cut}" &>/dev/null; then
            echo "Warning: shortcut \"${cut}\" already exists" >&2
        else        
            echo alias ${cut}="'cd ${dest}'"
            alias "${cut}"="'cd ${dest}'"
        fi
    done < <(
        sed -E -e 's/#[A-Za-z0-9 ]*$//' -e '/^\s+/s/^\s+//' -e '/^\s*$/d' "$@"
    )
    

    在“完成”之后,我正在重定向来自进程替换的输入:这避免了“while read”循环在子 shell 中运行。

    【讨论】:

      猜你喜欢
      • 2018-04-23
      • 2014-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-19
      • 1970-01-01
      • 1970-01-01
      • 2012-02-14
      相关资源
      最近更新 更多