当我运行以下脚本时出现以下错误:
cp: cannot stat ls
脚本内容
#!/bin/bash
#make copies of all files in directory
cd /home/don
LIST='ls'
for i in $LIST; do
ORIG=$i
DEST=$i.old
cp $ORIG $DEST
echo "Copied $i"
done
有人能看出问题所在吗?
答案1
主要错误之一是您尝试使用该ls
命令,但变量 LIST 仅包含字符串“ls”。您可以使用语法进行命令替换$(command)
。在这种情况下,我建议不要这样做,因为它不会以您可以轻松使用的格式提供信息。它几乎总是解析输出的错误ls
。
在这种情况下,你应该使用 shell 模式匹配,也称为通配符。
我建议您在脚本中采用以下方法:
#!/bin/bash
#make copies of all files in directory
for i in /home/don/* ; do
if [[ -f $i ]]; then
orig="$i"
dest="${i}.old"
cp "$orig" "$dest"
echo "Copied $i"
else
echo "${i} is not a file"
fi
done
- 这使用 shell 通配符来匹配目录中的所有文件。
./*
表示当前目录中的所有内容 (.
)。 - 该
if
语句检查匹配项是否为文件(目录和链接上会失败),如果是,则执行复制序列。 - 我已将变量名称改为小写,因为系统环境变量是大写的,这样您就可以避免任何不必要的名称冲突。
答案2
嗯,你的脚本中有一个小错误。在第四行中,你本想执行ls所以它不应该用单引号引起来,而应该用符号括起来``. 因此你的脚本将发生如下变化
LIST=`ls`
尝试按照上述方法更新您的脚本。
然而,建议$(ls)
根本不要使用,您应该更喜欢在循环头中使用 shell 通配符。
for i in *; do
就像安德森先生下面评论说这可以与变量值的引号一起使用(“ $i ”) 否则可能会导致文件名中出现空格问题。您可以使用 find 结合进程替换来防止这种情况:
while read l; do
i=$(basename "$l")
done < <(find . -name '*' -maxdepth 1)
下面给出了带有脚本和解释的详细答案阿罗尼卡尔先生。请参考它以便将来编写更好的脚本。
答案3
‘find’ 命令版本
您的脚本可以作为单行find
命令完成,而无需解析ls
或处理 glob 等。
就问题而言,您的目标是复制当前目录中的所有文件。为此,适当的命令将是:
find . -maxdepth 1 -mindepth 1 -exec cp {} {}".old" \;
它的作用是find
操作 (当前) 目录中的所有文件.
并调用cp
每个文件 (因此\;
)。因为find
是递归的,所以我们必须限制搜索的深度,因此使用-maxdepth
flag,并且-mindepth
flag 是为了避免列为.
搜索结果之一。
示例运行:
$ touch "file one" "file two"
$ find . -maxdepth 1 -mindepth 1 -exec cp {} {}".old" \;
$ ls -1
file one
file one.old
file two
file two.old
$
笔记:cp
仍会抱怨目录。有几种方法可以解决这个问题。
1)如果你的目标是使用类似这样的-type f
标志,那么你可以只过滤掉文件find
find . -mindepth 1 -maxdepth 1 -type f -exec cp {} {}".old" \;
2)cp -r
也用于复制目录
find . -mindepth 1 -maxdepth 1 -exec cp -r {} {}".old" \;
Python 单行代码
这比那个稍微长find
一点,但仍然可以完成工作,并且没有特殊文件名的问题。
python -c 'import shutil; import os;[shutil.copyfile(f,f + ".old") for f in os.listdir(".") if os.path.isfile("./" + f)]'
示例运行:
$ touch "test file 1" "testfile 2"
$ python -c 'import shutil;import os;[shutil.copyfile(f,f + ".old")
> for f in os.listdir(".")
> if os.path.isfile("./" + f)]'
$ ls -1
test file 1
test file 1.old
testfile 2
testfile 2.old
$
要包含目录,使用shutil.copytree(source,destination)
python -c 'import shutil; import os;[shutil.copyfile(f,f + ".old") if os.path.isfile("./" + f) else shutil.copytree(f,f + ".old") for f in os.listdir(".")]'
directory_one.old/
请注意,如果 say已经存在,则此操作将失败