【发布时间】:2011-02-24 00:00:58
【问题描述】:
我经常想对目录中的所有文件(包括隐藏文件)执行命令。当我尝试使用
chmod g+w * .*
它更改了我想要的所有文件(在目录中)和父目录中的所有文件(我想单独留下)的权限。
是否有通配符可以做正确的事情,还是我需要开始使用 find?
【问题讨论】:
我经常想对目录中的所有文件(包括隐藏文件)执行命令。当我尝试使用
chmod g+w * .*
它更改了我想要的所有文件(在目录中)和父目录中的所有文件(我想单独留下)的权限。
是否有通配符可以做正确的事情,还是我需要开始使用 find?
【问题讨论】:
通常我只会使用. .[a-zA-Z0-9]*,因为我的文件名往往遵循某些规则,但这不会涵盖所有可能的情况。
您可以使用:
chmod g+w $(ls -1a | grep -v '^..$')
它基本上会列出所有文件和目录,去掉父目录,然后处理其余的。但请注意文件名中的空格,它会将它们视为单独的文件。
当然,如果你只是想做文件,你可以使用:
find . -maxdepth 0 -type f -exec chmod g+w {} ';'
或者,另一种解决方案,它应该执行除.. 之外的所有文件和目录:
for i in * .* ; do if [[ ${i} != ".." ]] ; then chmod g+w "$i"; fi done
但现在您进入了可能需要脚本或别名的领域。
【讨论】:
您将需要两个 glob 模式来覆盖所有潜在的“点文件”:.[^.]* 和 ..?*。
第一个匹配具有两个或多个字符的所有目录条目,其中第一个字符是点,第二个字符不是点。第二个选择包含三个或更多以.. 开头的字符的条目(这不包括..,因为它只有两个字符并且以. 开头,但包括(不太可能)像..foo 这样的条目。
chmod g+w .[^.]* ..?*
这应该适用于大多数 shell,并且适用于脚本。
对于常规的交互使用,模式可能很难记住。对于这些情况,您的 shell 可能有一种更方便的方式来跳过 . 和 ..。
zsh 总是从.* 等模式中排除. 和..。
使用 bash,您必须使用 GLOBIGNORE shell 变量。
# bash
GLOBIGNORE=.:..
echo .*
您可以考虑在您的 bash 自定义文件之一中设置 GLOBIGNORE(例如 .bash_profile/.bash_login 或 .bashrc)。
但是,如果您经常使用其他环境,请注意习惯这种自定义。
如果您在缺少自定义的环境中运行类似 chmod g+w .* 的命令,那么您最终会意外地在命令中包含 . 和 ..。
此外,您可以将 shell 配置为在不以显式点开头的模式中包含“点文件”(例如 *)。
# zsh
setopt glob_dots
# bash
shopt -s dotglob
# show all files, even “dot files”
echo *
【讨论】:
( GLOBIGNORE=.. ; echo .* ) 暂时进行此操作。 +1 仅针对那一点信息。
怎么样:
shopt -s dotglob
chmod g+w ./*
【讨论】:
由于您可能不想为 bash 会话的其余部分设置 dotglob,因此您可以通过在子进程中运行来为一组命令设置它,如下所示:
$ (shopt -s dotglob; chmod g+w ./*)
【讨论】:
我做的是
tar --directory my_directory --file my_directory.tar --create `ls -A mydirectory/`
工作得很好ls -A my_directory 扩展到目录中除. 和.. 之外的所有内容。没有奇怪的球体,而且在一条线上。
ps:也许有人会告诉我为什么这不是一个好主意。 :p
【讨论】:
如果您确定永远不会使用两个字符的隐藏文件名,那么最简单的选择就是这样做:
chmod g+w * ...*
【讨论】: