我有一个问题,可能有也可能没有我正在寻找的形式的答案,但任何形式都足够了。
我当前有一个配置文件,在其中我将使用 shell 命令,该命令使用 grep 查找文件中的特定行,然后使用 sed 获取特定字符后的所有文本。其余文本只是包含环境变量的文件路径。该命令的输出返回如下内容:
$LIGHTS_HOME/music/something.mp3
然后我想将其通过管道传输到 mp3info 以从 mp3 文件中获取可用的元数据。但是,当我将其通过管道传输到 mp3info $LIGHTS_HOME 时,它不会扩展到与其相关的实际文件路径。如何在一行内扩展它?这可能吗?
这是我当前的命令:
$ sudo grep -w "file_path =" /home/pi/lightshowpi/config/state.cfg |
sed 's/.*= //' | sed 's|'\$LIGHTS_HOME'| '/home/pi/lightshowpi'|' |
xargs mp3info -p "Now Playing: %t by %a" | xargs sudo python /home/pi/lightshowpi/tweet/tweet.py
该命令正在做什么(我已经编辑了该行,以便更容易阅读,在使用中它将需要是单行(最好,如果需要,我可以使用多行):
第一行使用 grep 查找行 'file_path =',它返回行 'file_path = $LIGHTS_HOME/music/songname.mp3'
然后将其通过管道传输到 sed,后者解析该语句并返回“=”之后的所有字符,在本例中返回“$LIGHTS_HOME/music/songname.mp3”
从那里我使用第二个 sed 命令将 $LIGHTS_HOME 替换为其变量值 '/home/pi/lightshowpi/'
理想情况下,我想摆脱第二个 sed 语句,转而使用将 '$LIGHTS_HOME' 评估为其值 '/home/pi/lightshowpi/' 的内容
然后 mp3info 将使用它来获取文件的元数据,该文件被格式化为 stdout,然后通过管道传输到 xargs,xargs 将元 stdout 准备为 python 脚本使用的 stdin 格式,并用其他一些值发送该值表情符号字符(Python 脚本执行此操作没有问题)
但是,我宁愿扩展 $LIGHTS_HOME,而不是使用第二个 sed 命令来替换 /home/pi/lightshowpi,因为在其他安装中,可以将此变量设置在主目录以外的位置。
我想我应该注意,我正在终端中尝试此操作,我没有将其放入 shell 脚本中。我不确定这是否会改变事情,我仍在尽最大努力学习 shell,但我相信这可能会根据我不断收到的错误而改变事情。
答案1
(e)
使用 ZSH,您可以使用给定变量中某些内容的参数扩展标志“执行参数扩展、命令替换和算术扩展” x
(zshexpn(1)
详细信息请参阅):
x='$HOME/blablah'; echo $x; echo ${(e)x}
或者来自文件:
echo '$HOME/fromfile' > afile
echo ${(e)$(<afile)}
与 相比,这具有多种优点eval
,具体取决于谁有权访问配置文件以及他们有多顽皮:
$ touch somefile
$ echo 'hi; rm somefile' > x
$ eval "echo `cat x`"
hi
$ ls somefile
ls: somefile: No such file or directory
$ exec zsh
% touch somefile
% echo ${(e)$(<x)}
hi; rm somefile
% ls somefile
somefile
%
答案2
本质上,这行代码在配置文件 /home/pi/lightshowpi/config/state.cfg 中搜索“file_path =”行,然后将环境变量 $SYNCHRONIZED_LIGHTS_HOME 扩展为其值,并将其通过管道传输到 mp3info,后者从其中提取元数据然后,MP3 文件将字符串通过管道传输到 Python 脚本,该脚本接受参数并删除不需要的字符,同时包含 Python 表情符号库中的表情符号,以便通过 Twitter API 向您的帐户发送推文。
sed '/file_path =/!d;s|.*= ||;s|$SYNCHRONIZED_LIGHTS_HOME|'"$SYNCHRONIZED_LIGHTS_HOME|" /home/pi/lightshowpi/config/state.cfg | xargs mp3info -p "Now Playing %t by %a" | xargs sudo python /home/pi/lightshowpi/tweet/tweet.py
该命令的关键是使用!排除“file_path =”,然后对 mp3info 和 tweet.py 使用 xargs
我将调试以下 /home/pi/lightshowpi/config/state.cfg 使用相同的变量 $SYNCHRONIZED_LIGHTS_HOME 而不是 /home/pi/lightshowpi 以使此命令对该开源项目通用。
答案3
假设变量 $myvar 中有值 $LIGHTS_HOME/music/something.mp3
您可以通过以下方式扩展它:
mp3info $(eval echo $myvar)