我在计算机上做了一些破坏,当我使用vezult [1].建议的命令时,我希望单行代码要求删除文件名。但是,它立即删除了我在文件夹中的文件:
> find ./ -type f | while read x; do rm "$x"; done
我希望它等待我输入stdin:s [2]。我无法理解它的行动。 read命令如何工作,以及在哪里使用它?
答案 0 :(得分:4)
read
从stdin
读取的内容是file1
file2
。当你把它放在管道的末端时,它会从那个管道中读取。
所以你的发现变成了
read
等等; x
读取并file1
依次替换file2
然后 find . -type f
,因此您的循环变为
rm“file1” rm“file2”
果然,rm的每个文件从当前目录“。”开始。
一些提示。
你不需要“/”。说
更好更安全. /
因为你碰巧键入“.
”(即点空格斜杠),find将从当前目录开始,然后从根目录开始。如果拥有正确的权限,该技巧将删除计算机中的每个文件。 “.
”已经是目录的名称;你不需要添加斜杠。
听起来你想要做的就是浏览从当前目录“ find . -type f -exec rm -i {} \;
”开始的所有目录中的所有文件,如果你想要删除它,请让它为ASK它。你可以用
find . -type f -ok rm {} \;
或
rm -r -i *
根本不需要循环。你也可以
rm -i `find . -type f`
并获得几乎相同的效果,但它也会尝试删除目录。如果目录为空,那甚至可以正常工作。
另一种想法想想看,除非你有很多文件,你也可以这样做
-i
现在,反引号中的查找将成为命令行中的一堆文件名,rm
上的“{{1}}”交互标记将询问是或否。
答案 1 :(得分:3)
答案是 - 当你想从某个文件中读取连续的行(很可能是管道中某些先前命令序列的标准输出)时,可能会将这些行分成几个单独的变量。拆分是使用当前值“$IFS
”完成的,这通常意味着在空白和制表符上(换行符不在此上下文中计算;它们将行分开)。如果读命令中有多个变量,则第一个字进入第一个变量,第二个进入第二个变量,......,并将行的残余变为最后一个变量。如果只有一个变量,则整行进入该变量。
有很多用途。这是我使用拆分选项的简单脚本之一:
#!/bin/ksh
#
# @(#)$Id: mkdbs.sh,v 1.4 2008/10/12 02:41:42 jleffler Exp $
#
# Create basic set of databases
MKDUAL=$HOME/bin/mkdual.sql
ELEMENTS=$HOME/src/sqltools/SQL/elements.sql
cat <<! |
mode_ansi with log mode ansi
logged with buffered log
unlogged
stores with buffered log
!
while read dbs logging
do
if [ "$dbs" = "unlogged" ]
then bw=""; cw=""
else bw="-ebegin"; cw="-ecommit"
fi
sqlcmd -xe "create database $dbs $logging" \
$bw -e "grant resource to public" -f $MKDUAL -f $ELEMENTS $cw
done
带有here-document的cat
命令将其输出发送到管道,因此输出进入while read dbs logging
循环。第一个单词进入$dbs
,是我想要创建的(Informix)数据库的名称。该行的其余部分放入$ logging。循环体处理未记录的数据库(begin
和commit
不起作用),然后运行程序sqlcmd
(完全独立于同名的Microsoft新手;自1990年左右开始创建一个数据库并用一些标准表和数据填充它 - 模拟Oracle'dual
'表,以及一组与'元素表'相关的表。< / p>
使用read
命令的其他脚本更大(到目前为止),但通常读取包含一个或多个文件名和其他相关属性的行,然后使用属性对文件应用适当的转换
Osiris JL: file * | grep 'sh.*script' | sed 's/:.*//' | xargs wgrep read
esqlcver:read version letter
jlss: while read directory
jlss: read x || exit
jlss: read x || exit
jlss: while read file type link owner group perms
jlss: read x || exit
jlss: while read file type link owner group perms
kb: while read size name
mkbod: while read directory
mkbod:while read dist comp
mkdbs:while read dbs logging
mkmsd:while read msdfile master
mknmd:while read gfile sfile version notes
publictimestamp:while read name type title
publictimestamp:while read name type title
Osiris JL:
'Osiris JL:'是我的命令行提示;我在'bin'目录中运行了这个。 'wgrep
'是grep的变体,只匹配整个单词(以避免像'已经'这样的单词)。这给出了我如何使用它的一些指示。
'read x || exit
'行用于从标准输入读取响应的交互式脚本,但如果命令获得EOF则退出(例如,如果标准输入来自/dev/null
)。