如何在Bash Shell中接收标准输入并将其用于设置环境变量?

7

我正在尝试改进我的一行代码技巧,这是我目前拥有的。

$ echo $PATH
/home/ubuntu/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

我想做的是去掉第一个块,以下是我目前所了解到的内容---

$ echo $PATH | sed -e "s|^/[A-Za-z/]*:||"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

我在这里想做的最后一件事就是将其放回到 PATH 中,例如 export PATH=[那个结果]

我尝试的方法如下,但无法实现 ---

$ echo $PATH | sed -e "s|^/[A-Za-z/]*:||" | xargs export PATH=
xargs: export: No such file or directory

另外,顺便提一下,让我困惑的另一个问题是关于上面的sed表达式,不知何故,当我尝试使用+而不是*时,它无法捕获第一部分。看一下 ---

$ echo $PATH | sed -e "s|^/[A-Za-z/]+:||" 
/home/ubuntu/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

这就像“+”表示“一个或多个”,但与“*”表示“许多”相比,“+”的效果不太好。

3个回答

11

我认为针对那个特定的问题,最好的解决方案是:

export PATH=${PATH#*:}

但是这并没有回答如何使用 stdin 来设置环境变量的问题。

使用某些进程的 stdout 是很容易的:

export PATH=$(make_new_path)

但严格来说并没有使用 stdin。一个显而易见的解决方案:

make_new_path | export PATH=$(cat)

由于位于管道右侧的命令会在子shell中执行,因此变量设置不会生效,所以这个方法无法工作。(如果它能够工作,那么它将是一个UUOC)

正如Gordon Davisson在评论中指出的那样,你可以简单地使用:

read -r PATH; export PATH

实际上,并不需要export PATH,因为PATH已经预先导出,但我保留了它,以防您想使用其他环境变量。


如果他真的想使用脚本的STDIN,而不是某个命令的STDOUT,正确的做法是使用read PATH -- 但这根本不是这里所需要的。 - Gordon Davisson
1
@GordonDavisson:说得好。我会修复它。虽然这不是我们需要的,但这是问题的标题。 - rici
如果你想要变得荒谬(并且与除了bash之外的任何东西都不兼容),你可以使用进程重定向:read PATH < <(make_new_path) - Gordon Davisson
+1 我认为他真正想说的是STDOUT,写错了成了STDIN。你做得很对,回答了“意图”,而不是字面上的问题。你还很友善地添加了 read -r 选项。 - janos
可以在读取时添加“-s”以抑制回显。 - Ben Aveling

2
export PATH=$(echo "$PATH" | sed -e "s|^/[A-Za-z/]*:||")

“export”是shell内置命令,这就是为什么您不能直接通过“xargs”执行它(没有可执行文件来运行“export”)。此命令将运行您的编辑脚本,并将该值设置为$PATH的新值。使用双引号将$PATH括起来编写,即使在您的路径元素中有多个相邻空格的情况下也能正常工作(这种情况可能不太可能出现,但确保它正常工作是没有坏处的)。


echo $var е’Ң echo "$var" жҳҜзӣёеҗҢзҡ„гҖӮжӮЁдёҚйңҖиҰҒйӮЈдәӣеј•еҸ·гҖӮжӯӨеӨ–пјҢz=$(echo a b) дёҺ z="$(echo a b)" е’Ң z="$(echo "a b")" зӣёеҗҢгҖӮ - janos
2
@janos,echo "$var"echo $var非常不同--尝试使用var='*'或更微妙地使用var="two spaces"(单词之间有2个空格)。bash允许您省略变量赋值的双引号。 - glenn jackman
@glennjackman 哇,你说得对!我也忽略了“多个相邻空格”的部分,我的错,谢谢提醒! - janos

1
这是一个更简单和准确的内容:
echo "$PATH" | sed -e s/[^:]*://

正则表达式更准确,即使第一段有数字或空格也可以使用。

顺便说一下,您不需要导出,因为 PATH 已经导出。

正则表达式的实现取决于工具。据我所知,在 sed 中不起作用,您可以改用以下方法:

echo "$PATH" | sed -e 's/[^:]\{1,\}://'

在我的看法中,sed 中的正则表达式与 vim 相似,但与 perl 不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接