如何使 bash 替换 $(

如何使 bash 替换 $(

我想更换猫:

var=$(cat "filename" 2>/dev/null)

通过 bashism 语法:

var=$(<"filename")

问题是我不知道如何让攻击保持沉默以避免此类警告:

bash: filename: No such file or directory

我试过这个:

var=$(2>/dev/null <"filename")

但它不再读入现有文件var

答案1

将分配包装到复合块中并使用重定向似乎可行:

{ var=$(<"$file"); } 2>/dev/null;

例如

$ echo hello > test1; rm -f test2
$ file=test1; { var=$(<"$file"); } 2>/dev/null; echo "${var:-[it is empty]}"
hello
$ file=test2; { var=$(<"$file"); } 2>/dev/null; echo "${var:-"[it is empty]"}"
[it is empty]

只是不要用来( .. )创建子shell,因为那样分配的变量就会丢失。

答案2

首先进行测试以确保其可用且可读:

if [ -f "filename" ] && [ -r "filename" ]; then
    var=$(<"filename")
fi

-f测试测试是否filename指的是常规文件并且-r测试测试您是否可以阅读它。

答案3

另一种方法是首先检查文件是否存在,然后将其读入变量。

[ -e filename ] && var=$(<filename)

答案4

以供参考:

在 中zsh,您可以使用特殊的关联数组,该数组映射到名为键的文件的内容(请注意,它与内置函数(不映射文件)$mapfile无关,并且比内置函数(不映射文件)早十年左右)。它使用so 只能用于常规文件。bashmapfilemmap()

zmodload zsh/mapfile
var=$mapfile[filename]

如果文件无法打开或映射,它不会输出任何内容。要检查错误,可以使用$ERRNO特殊变量:

ERRNO=0
var=$mapfile[filename]
if ((ERRNO)); then
  : the mapping failed
fi

$ERRNO值可以使用模块中的数组转换为ENOENT, EACCESS... 代码,也可以使用内置函数转换为错误字符串。$errnoszsh/systemsyserrorzsh/system

您还可以mapfile[filename]=$var更改文件的内容,它是真正的映射。

请注意, while$(<filename)会剥离全部filename,内容中的尾随换行符$mapfile[filename]按原样扩展为文件的整个内容(包括二进制文件)。

相关内容