以 sudo [duplicate] 身份执行脚本时找不到 bash 内置命令 compgen

bash built-in command compgen is not found when executing a script as sudo [duplicate]

提问人:f1fan44 提问时间:11/17/2023 最后编辑:f1fan44 更新时间:11/17/2023 访问量:33

问:

我的目录中有一组压缩包。我想选择压缩包的“最大”名称(即以相反顺序排序时的第一个名称)并在 bash 脚本变量中捕获该名称。我的示例文件是:

goyard@GoYard-BOXER-6404:~/Code/NodejsServer$ ls
reports-1.0.0.tgz  reports-1.1.0.tgz  reports-2.tgz

在这种情况下,“reports-2.tgz”是我想要的文件。

在 bash 命令行中,这工作正常:

goyard@GoYard-BOXER-6404:~/Code/NodejsServer$ tarball_path=`compgen -G "report*.tgz" | sort -r | head -n 1`
goyard@GoYard-BOXER-6404:~/Code/NodejsServer$ echo $tarball_path
reports-2.tgz

在 bash shellscript 中,相同的命令成功:

脚本:

# !/bin/bash

tarball_path=`compgen -G "report*.tgz" | sort -r | head -n 1`
echo "tarball_path: ${tarball_path}"

脚本输出:

goyard@GoYard-BOXER-6404:~/Code/NodejsServer$ ./get_report_name.sh
tarball_path: reports-2.tgz

但是当我使用 sudo 执行脚本时,找不到 compgen 内置命令:

goyard@GoYard-BOXER-6404:~/Code/NodejsServer$ sudo ./get_report_name.sh
[sudo] password for goyard:
./get_report_name.sh: 1: compgen: not found
tarball_path:

我需要使用 sudo,因为我最终会将这个 tarball 提取到我的 Ubuntu 盒子上的 /srv 目录中。

注意:这似乎不是使用 bash -e 选项的问题,因为 compgen 命令内置于 bash - 未入。

为什么 sudo 在这里有所作为?

...我该如何纠正这个问题?

bash sudo compgen

评论

0赞 Charles Duffy 11/17/2023
CompGen 是一个交互式扩展。它根本不能保证在非交互式 shell 中可用,在某些 Linux 发行版 (NixOS f/e) 上,用于脚本执行的默认 bash(与人工操作的交互式 shell)是在关闭交互式扩展的情况下编译的。请注意,您肯定不在 NixOS 上,因为在那里不能作为 shebang 工作。#!/bin/bash
0赞 Charles Duffy 11/17/2023
也就是说,我不清楚为什么你在这里需要compgen。 然后你就完成了 -- 你可以打电话。或者做一些使用间接赋值保存到命名变量的事情,以消除命令替换并获得相应的效率提升。而且,如果您仅在通过 sudo 使用仅 bash 语法时才收到语法错误,这将为我们提供有关您的问题的更多提示。lastMatch() { local val="${@:$#}"; if [[ -e $val || -L $val ]]; then printf '%s\n' "$val"; else return 1; fi; }tarball_path=$(lastMatch report*.tgz)
2赞 Charles Duffy 11/17/2023
另一件事 -- 不是有效的 shebang;取出空间,所以它只是.如果您的脚本作为后备执行(这将解释不可用),这实际上可能会解决问题。当你从 bash 开始并且 execve 失败时,它会尝试将自己用作解释器,这将解释它们看起来像是交互式工作的事情,即使它们在更一般的情况下不起作用。# !/bin/bash#!/bin/bashshcompgen
0赞 Charles Duffy 11/17/2023
请参阅 echo -e 在 ubuntu 上由 root 在脚本中运行时的行为不同,以了解具有相同根本原因的不同问题(也就是说,由没有有效 shebang 的脚本运行,而不是在 Ubuntu 上启动时)。shbashsudo
0赞 Charles Duffy 11/17/2023
(就个人而言,我在团队中“sudo 和 bash 都不应该实现这种'有用'的后备行为;相反,当 execve() 不起作用时,它们应该显式失败“;但唉,我不统治世界)

答: 暂无答案