如何让Bash读取文件时解析$(command)命令替换语法?
问题:从文件读取带变量的包名执行dpkg命令失败的解决办法
在Bash命令行直接执行以下命令,能正常匹配到对应版本的内核头文件包:
$ pkg="linux-headers-$(uname -r)" $ dpkg -l "${pkg}" | grep '^ii ' ii linux-headers-5.15.0-130-generic 5.15.0-130.140~20.04.1 amd64 Linux kernel headers for version 5.15.0 on 64 bit x86 SMP
但将包名写入文件后,读取文件内容执行命令时,带$(uname -r)的包名无法被正确解析,导致命令失败。
创建包列表文件的步骤
$ echo "build-essential" > pkgs.list $ echo "linux-headers-\$(uname -r)" >> pkgs.list $ echo "gcc" >> pkgs.list $ cat pkgs.list build-essential linux-headers-$(uname -r) gcc
读取文件执行命令的错误结果
$ IFS=$'\n' ; while read pkgline ; do dpkg -l "${pkgline}" | grep '^ii ' ; done < pkgs.list ii build-essential 12.8ubuntu1.1 amd64 Informational list of build-essential packages dpkg-query: no packages found matching linux-headers-$(uname -r) ii gcc 4:9.3.0-1ubuntu2 amd64 GNU C compiler
需求是:不替换文件中的$(uname -r)变量形式,让循环内的dpkg -l命令能像命令行直接执行时一样正确解析变量。
之前尝试的错误用法
之前试过多种错误的eval用法均无效,例如:
dpkg -l eval ${pkgline} dpkg -l ${!pkgline} p=eval "${pkgline}" ; dpkg -l "${p}" dpkg -l "eval echo -e ${pkgline}"
正确解决方案
只需在dpkg -l前添加eval,让Shell先解析变量再执行命令:
IFS=$'\n' ; while read pkgline ; do eval dpkg -l "${pkgline}" | grep '^ii ' ; done < pkgs.list
执行后,linux-headers-$(uname -r)会被正确替换为当前内核版本对应的包名,dpkg就能正常匹配并返回结果。
内容的提问来源于stack exchange,提问作者JSJ
相关产品推荐
相关产品推荐

