如果您的用户没有足够的权限/home/hejhej
列出其内容,则会发生这种情况。
当你运行时:
sudo ls -d /home/hejhej/*/
是您的外壳尝试进行文件名通配。如果它不能读取那个目录,它就不能展开任何东西。因此,文字字符串/home/hejhej/*/
保持原样,并作为参数传递给通过vials
运行。看来您没有在该目录中调用目录,因此失败。root
sudo
*
ls
你需要 shell 开始sudo
在这里做 globbing。一种选择可能是:
sudo sh -c 'ls -d /home/hejhej/*/'
如果您希望搜索的文件夹包含一个 shell 变量,那么'
硬引号将不起作用 - 这可以防止您的 shell 出现通配符(好),但也可以防止您的 shell 进行变量扩展(这里不好)。您应该改用双引号 ( "
),以便您的 shell 完成变量扩展:
sudo sh -c "ls -d /home/$username/*/"
如果您想将该命令的输出捕获到变量中,请更喜欢$()
命令替换的形式而不是反引号 ( `
) - 更容易引用:
result=$(sudo sh -c "ls -d /home/$username/*/")
现在如果$username
可以包含空格(比如username="hello world"
),上面的内容将不起作用 - 根 shell 将看到两个“标记”(/home/hello
和world/*/
)。你可以用另一层引号来解决这个问题:
result=$(sudo sh -c "ls -d /home/'$username'/*/")
考虑到引号的嵌套方式,这不会阻止您的 shell 扩展$username
,但将使根 shell 能够在单个模式上正确地 glob /home/hello world/*/
。
现在,这仍然不完美。如果该 glob 匹配多个目录,或者匹配的目录包含空格,您将很难处理问题。但在这一点上,我建议你:
- 阅读此建议:为什么不应该解析 ls 的输出?
- 制作一个由 root 运行的适当脚本来处理查找适当的目录 - 如果它们简短且易于阅读,那么单行就可以了。一旦事情变得过于复杂,从长远来看,编写一个合适的脚本是一种胜利。
话虽这么说,如果您希望将另一个用户家中的目录列表放入一个数组中,那么以下(我认为特定于 bash)应该这样做,没有解析问题ls
,并且应该处理文件和目录中的空格:
while read -r -d $'\0' dir ; do
array+=("$dir")
done < <(sudo find "/home/$username" -maxdepth 1 -mindepth 1 -print0)