例如,现在我正在使用以下内容来更改我将其 Unix 路径写入文件的几个文件:
cat file.txt | while read in; do chmod 755 "$in"; done
有没有更优雅、更安全的方式?
这是因为不仅有1个答案…
xargs
while read
while read -u
fd
关于 OP 请求: _ 在 file 中列出的所有目标上 _ 运行chmod,xargs是指示的工具。但是对于其他一些应用程序,少量文件等......
chmod
如果您的文件不是太大并且所有文件都 命名良好 (没有空格或其他特殊字符,如引号),您可以使用 shell 命令行扩展 。简单地:
chmod 755 $(<file.txt)
对于少量文件(行),此命令是较轻的命令。
对于更大数量的文件,或输入文件中几乎 任意 数量的行…
对于许多 binutils 工具,如chown, chmod, rm, cp -t…
chown
rm
cp -t
xargs chmod 755 <file.txt
如果您在file.txt.
file.txt
xargs -0 chmod 755 < <(tr \\n \\0 <file.txt)
如果您的命令需要为每个条目准确运行 1 次:
xargs -0 -n 1 chmod 755 < <(tr \\n \\0 <file.txt)
此示例不需要这样做,因为它chmod接受多个文件作为参数,但这与问题的标题相匹配。
对于某些特殊情况,您甚至可以在以下命令生成的命令中定义文件参数的位置xargs:
xargs -0 -I '{}' -n 1 myWrapper -arg1 -file='{}' wrapCmd < <(tr \\n \\0 <file.txt)
seq 1 5
尝试这个:
xargs -n 1 -I{} echo Blah {} blabla {}.. < <(seq 1 5) Blah 1 blabla 1.. Blah 2 blabla 2.. Blah 3 blabla 3.. Blah 4 blabla 4.. Blah 5 blabla 5..
您的命令每行执行一次。
正如OP建议的那样,
cat file.txt | while read in; do chmod 755 "$in" done
会工作,但有两个问题:
cat |是一个 无用的叉子 ,并且
cat |
| while ... ;done将成为一个 子shell ,其环境将在之后消失;done。
| while ... ;done
;done
所以这可以更好地写:
while read in; do chmod 755 "$in" done < file.txt
但
$IFS
read
help read
read: read [-r] ... [-d delim] ... [name ...] ... Reads a single line from the standard input... The line is split into fields as with word splitting, and the first word is assigned to the first NAME, the second word to the second NAME, and so on... Only the characters found in $IFS are recognized as word delimiters. ... Options: ... -d delim continue until the first character of DELIM is read, rather than newline ... -r do not allow backslashes to escape any characters ... Exit Status: The return code is zero, unless end-of-file is encountered...
在某些情况下,您可能需要使用
while IFS= read -r in;do chmod 755 "$in" done <file.txt
避免出现奇怪文件名的问题。也许如果您遇到 UTF-8 的问题:
while LANG=C IFS= read -r in ; do chmod 755 "$in" done <file.txt
当您使用来自标准输入for readingfile.txt` 的重定向时,您的脚本无法以交互方式读取其他输入(您不能再将标准输入用于其他输入)。
for reading
语法:while read ...;done <file.txt将标准输入重定向到来自file.txt. 这意味着您将无法处理流程,直到它们完成。
while read ...;done <file.txt
这将让您同时使用多个输入,您可以合并两个文件(如这里:scriptReplay.sh),或者也许:
您计划创建一个 交互式 工具,您必须避免使用标准输入并使用一些替代文件描述符。
常量文件描述符是:
“显示标记为“posix”的问题”) shell优先
您可以通过以下方式查看它们:
ls -l /dev/fd/
或者
ls -l /proc/$$/fd/
从那里,您必须选择 0 到 63 之间的未使用数字(实际上,更多,取决于sysctl超级用户工具)作为您的文件描述符。
sysctl
对于这个演示,我将使用文件描述符 7:
while read <&7 filename; do ans= while [ -z "$ans" ]; do read -p "Process file '$filename' (y/n)? " foo [ "$foo" ] && [ -z "${foo#[yn]}" ] && ans=$foo || echo '??' done if [ "$ans" = "y" ]; then echo Yes echo "Processing '$filename'." else echo No fi done 7<file.txt
如果您想以更多不同的步骤读取输入文件,则必须使用:
exec 7<file.txt # Without spaces between `7` and `<`! # ls -l /dev/fd/ read <&7 headLine while read <&7 filename; do case "$filename" in *'----' ) break ;; # break loop when line end with four dashes. esac .... done read <&7 lastLine exec 7<&- # This will close file descriptor 7. # ls -l /dev/fd/
“显示标记为“bash”的问题”)
在bash下,您可以让他 fd 为您选择任何免费并存储到变量中 exec {varname}</path/to/input:
exec {varname}</path/to/input
while read -ru ${fle} filename;do ans= while [ -z "$ans" ]; do read -rp "Process file '$filename' (y/n)? " -sn 1 foo [ "$foo" ] && [ -z "${foo/[yn]}" ] && ans=$foo || echo '??' done if [ "$ans" = "y" ]; then echo Yes echo "Processing '$filename'." else echo No fi done {fle}<file.txt
exec {fle}<file.txt # ls -l /dev/fd/ read -ru ${fle} headline while read -ru ${fle} filename;do [[ -n "$filename" ]] && [[ -z ${filename//*----} ]] && break .... done read -ru ${fle} lastLine exec {fle}<&- # ls -l /dev/fd/