xBe*_*ker 4 command-line bash scripts
问题是我正在为类做一个脚本,问题是“制作一个脚本来命名实际目录中的所有文件并告诉我们它们的名称和权限”,所以我制作了以下脚本:
#!/bin/bash
for name in `ls -l . | awk {print'$9'}`
do
echo "The file $name has the following permissions: `ls -l . | grep $name | cut -d" " -f1`"
done
Run Code Online (Sandbox Code Playgroud)
好的,脚本有点工作,但问题是它不会显示ls -l列表中的所有文件,因为我正在打印9th column(文件名)但如果它有空格,则空格后面的单词在column 10,所以我这样试过:
#!/bin/bash
for name in `ls -l . | awk {print'$9,$10'}`
do
echo "The file $name has the following permissions: `ls -l . | grep $name | cut -d" " -f1`"
done
Run Code Online (Sandbox Code Playgroud)
但是当我这样做时,问题是变量 $name 会将第一列和第二列作为单独的词引用,并且它会将两者都显示为不同的文件。
我也尝试在lsusing 中转义空格,ls -lb但是该grep命令将不起作用,如果我使用 grep '$name\s'它,它将逐字复制 $name\s,因此它不会在ls命令中搜索任何内容...
也许解决这个问题真的很容易,但我已经解决了 5 个多小时,没有任何帮助......感谢任何帮助!
for name in ./*; do
Run Code Online (Sandbox Code Playgroud)
还有其他方法可以改进脚本。
ls. 相反,使用stat直接获取权限。1$(...)而不是已弃用的反引号`...`$perms,使打印字符串更清晰、更易于阅读。所以:
for name in ./*; do
perms="$(stat -c "%A" "$name")"
echo "The file $name has the following permissions: $perms"
done
Run Code Online (Sandbox Code Playgroud)
脚注:
如果stat不存在,并且您必须从 获得权限ls,您可以将文件名作为参数,并使用该-d标志,这样它就不会进入目录或取消引用符号链接。
ls -ld "$name" | cut -d" " -f1
Run Code Online (Sandbox Code Playgroud)
但同样,你不应该解析ls. 如果任何文件名包含换行符,则此方法将失败。
写这样的东西绝对不是一个好计划
for stuff in `ls`; ...
Run Code Online (Sandbox Code Playgroud)
解析 的输出ls是一个非常糟糕的主意,因为 的输出ls只是文本,并且是文件实际名称的不可靠表示。
要处理文件,请改用 shell glob。
for stuff in *; ...
Run Code Online (Sandbox Code Playgroud)
代替*,您可以使用./*which 表示相同的事情,但更安全,因为所有路径都以./(当前目录)开头,而不是文件名开头的任何可疑符号,这可能是导致 shell 执行扩展(例如~)(尽管您绝对应该“引用”您的变量以防止此类不需要的 shell 扩展)或您尝试使用的命令可能会尝试特别解释的变量(例如-)。您也可以使用*and not ./*,但将--所有选项添加到您在循环中运行的命令中,以防止文件名开头-被解释为选项。这提供了一个干净的路径,但如果你想使用./*你有时可以使用"$(basename $var)"在命令或其他技巧中。请注意,并非所有命令都支持--指示选项结束。
与其尝试解析您想要的内容ls -l,不如使用专门用于显示文件元数据的命令并仅询问您想要的输出。
stat -c "%n %A" file
Run Code Online (Sandbox Code Playgroud)
应该给你你想要的。如果你想显示一条消息,你可以把它写在:)
这是我如何做到这一点:
for file in *; do stat -c 'The permissions of %n are: %A' -- "$file"; done
Run Code Online (Sandbox Code Playgroud)