例如,为了您的娱乐:
$ f=/etc/os-release; . $f; cat $f | sed -re 's/(.*)=.*/printf "%20s: %s\\n" "\\$\1" "$\1"/'
printf "%20s: %s\n" "\$NAME" "$NAME"
printf "%20s: %s\n" "\$VERSION" "$VERSION"
printf "%20s: %s\n" "\$ID" "$ID"
printf "%20s: %s\n" "\$ID_LIKE" "$ID_LIKE"
printf "%20s: %s\n" "\$PRETTY_NAME" "$PRETTY_NAME"
printf "%20s: %s\n" "\$VERSION_ID" "$VERSION_ID"
printf "%20s: %s\n" "\$HOME_URL" "$HOME_URL"
printf "%20s: %s\n" "\$SUPPORT_URL" "$SUPPORT_URL"
printf "%20s: %s\n" "\$BUG_REPORT_URL" "$BUG_REPORT_URL"
printf "%20s: %s\n" "\$PRIVACY_POLICY_URL" "$PRIVACY_POLICY_URL"
printf "%20s: %s\n" "\$VERSION_CODENAME" "$VERSION_CODENAME"
printf "%20s: %s\n" "\$UBUNTU_CODENAME" "$UBUNTU_CODENAME"
$
...现在是实际问题;
如何在本地 shell 中执行此操作,而不使用临时文件!?
(所以避免任何类似的东西... >z ; . z ; rm z
)
xargs 无法做到 (IIUC)
源 - 没有这样的选项
bash - 创建一个子外壳,因此不会看到变量值。
我尝试过的事情:
$ source <(f=/etc/os-release; . $f; cat $f | sed -re 's/(.*)=.*/printf "%20s: %s\\n" "\\$\1" "$\1"/')
$NAME:
$VERSION:
$ID:
$ID_LIKE:
$PRETTY_NAME:
$VERSION_ID:
$HOME_URL:
$SUPPORT_URL:
$BUG_REPORT_URL:
$PRIVACY_POLICY_URL:
$VERSION_CODENAME:
$UBUNTU_CODENAME:
$ source < <(f=/etc/os-release; . $f; cat $f | sed -re 's/(.*)=.*/printf "%20s: %s\\n" "\\$\1" "$\1"/')
bash: source: filename argument required
source: usage: source filename [arguments]
$ source /dev/fd/0 <(f=/etc/os-release; . $f; cat $f | sed -re 's/(.*)=.*/printf "%20s: %s\n" "\\$\1" "$\1"/')
^C # no output, CTRL-C
$
预期输出,我重复一遍 - 不使用临时文件/脚本:
$NAME: Ubuntu
$VERSION: 20.04.4 LTS (Focal Fossa)
$ID: ubuntu
$ID_LIKE: debian
$PRETTY_NAME: Ubuntu 20.04.4 LTS
$VERSION_ID: 20.04
$HOME_URL: https://www.ubuntu.com/
$SUPPORT_URL: https://help.ubuntu.com/
$BUG_REPORT_URL: https://bugs.launchpad.net/ubuntu/
$PRIVACY_POLICY_URL: https://www.ubuntu.com/legal/terms-and-policies/privacy-policy
$VERSION_CODENAME: focal
$UBUNTU_CODENAME: focal
解释:
在我的版本[上面]中(下面是@Scott的答案的副本)我没有在主shell中初始化来自/etc/os-release的变量,只有在子shell中。随之而来的是,它们不能由source <(...)
主 shell 打印。
因此,oneliner 的工作“更正”版本是:
f=/etc/os-release; source "$f"; source <( sed <"$f" -re 's/(.*)=.*/printf "%20s: %s\\n" "\\$\1" "$\1"/')
第一个source "$f";
初始化变量的地方,然后 subshell 生成要由source <(...)
. 上面
......为了便于阅读,这里的缩写.
被替换为。source
简短/一般答案:
您尝试的第一件事是正确的:如果
或者 事实上,在你的例子中,它工作正常。它没有给你想要的结果,因为……command-list
是一个命令列表,在运行时输出一个 shell 脚本(即另一个命令列表),您可以执行(动态创建的)脚本长/具体的答案:
......像
$(…)
和<(…)
(以及,就此而言,(…)
)创建子shell。您尝试的第一件事的问题是您正在 子shell中执行并且. $f
您正在外壳中执行命令。printf
所以解决方案是你需要.
在外壳中做:我在周围添加了双引号,
"$f"
因为它是正确的事情™;只要 的值不$f
包含时髦的字符,严格来说,您就不需要它们。而且,“当然”,您可以source
将上面的更改为另一个.
:我把 UUOC 留给你修了。