yq输出重定向至文件遇权限拒绝错误的原因排查
yq输出权限拒绝错误的可能原因 针对你遇到的echo hello | yq -r > temp报错Error: write /dev/stdout: permission denied,但命令替换或grep类似场景正常的情况,以下是几个可能的原因:
yq版本的已知bug:你使用的yq 4.26.1可能存在特定版本问题,部分旧版本yq在处理标准输出重定向时,会直接尝试打开
/dev/stdout而非继承父进程的文件描述符。如果当前环境中/dev/stdout的权限设置异常(比如当前用户无写入权限),就会触发这个错误。而命令替换$(...)是让yq在子shell中输出到父shell的缓冲区,而非直接写入/dev/stdout,因此绕过了这个问题。yq二进制文件的特殊权限设置:如果yq的可执行文件被设置了SUID/SGID位(比如通过
sudo chmod u+s yq修改过),那么yq会以文件所有者的身份运行,而非当前用户。如果所有者对/dev/stdout没有写入权限,就会出现拒绝错误。而grep通常不会有这类特殊权限,所以能正常运行;命令替换的方式下,yq的输出先传递给父shell,再由父shell写入文件,也避开了权限问题。安全模块的限制(如AppArmor):Ubuntu系统默认启用AppArmor,若yq被配置了严格的AppArmor profile,可能限制了它直接写入标准输出的行为。命令替换的执行路径可能未被该profile拦截,因此可以正常工作;而
grep的AppArmor规则通常更宽松,不会触发此类限制。文件描述符的异常继承:少数情况下,当前shell的文件描述符可能存在异常,yq没有正确继承管道传递的stdout文件描述符,转而尝试直接打开
/dev/stdout,但该设备文件的权限不允许当前操作。grep对文件描述符的处理更兼容,因此不受影响。
内容的提问来源于stack exchange,提问作者klynxe

