脚本中的 cp 错误

脚本中的 cp 错误

当我运行以下脚本时出现以下错误:

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是递归的,所以我们必须限制搜索的深度,因此使用-maxdepthflag,并且-mindepthflag 是为了避免列为.搜索结果之一。

示例运行:

$ 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已经存在,则此操作将失败

相关内容