Bash 用于备份当前目录中不使用多个参数的任何文件的Shell脚本

Bash 用于备份当前目录中不使用多个参数的任何文件的Shell脚本,bash,shell,Bash,Shell,我正在尝试编写一个脚本,该脚本创建作为参数解析的任何文件的备份。但在给出多个参数时,我得到一个错误: 文件test newtest不存在 代码: 情景1:(工作) 情景2:(不工作) 我做错了什么?你不能用-f测试多个文件名,你必须一次测试一个文件名。因此,将循环放在copy\u文件调用之外 #!/bin/bash copy_file() { cp "$1" "$1.backup" } for FILENAME in "$@&quo

我正在尝试编写一个脚本,该脚本创建作为参数解析的任何文件的备份。但在给出多个参数时,我得到一个错误:

文件test newtest不存在
代码:

情景1:(工作)

情景2:(不工作)


我做错了什么?

你不能用
-f
测试多个文件名,你必须一次测试一个文件名。因此,将循环放在
copy\u文件
调用之外

#!/bin/bash

copy_file() {
    cp "$1" "$1.backup"
}

for FILENAME in "$@"
do
    if ! [ -f "$FILENAME" ]; then
        echo "The file $FILENAME  does not exist";
    else
        echo "The file $FILENAME exists. Copying file"
        copy_file "$FILENAME"
    fi
done

不能使用
-f
测试多个文件名,必须一次测试一个文件名。因此,将循环放在
copy\u文件
调用之外

#!/bin/bash

copy_file() {
    cp "$1" "$1.backup"
}

for FILENAME in "$@"
do
    if ! [ -f "$FILENAME" ]; then
        echo "The file $FILENAME  does not exist";
    else
        echo "The file $FILENAME exists. Copying file"
        copy_file "$FILENAME"
    fi
done

除了您的方法会失败这一事实之外,如果您的脚本通过了一个包含空格的文件名,那么您的脚本就会自相矛盾:在
copy_file
中,您假定
filename
包含一组文件名(因为您要循环这些文件名),而接下来,您会执行
[-f“$filename”]
,这意味着您假设
FILENAME
包含一个文件名。你必须下定决心,你的变量的内容是什么

现在,如何修复它:您似乎想要处理文件名列表,如果文件不存在,则发出错误消息。如果它存在,您希望创建一个备份副本,并编写一条消息说明您这样做了。因此,您需要循环传递给脚本的参数:

#!/bin/bash
for filename in "$@"
do
    cp -v "$filename" "$filename.backup"
done
检查是否存在由
cp
完成,复制时打印有意义的消息由
-v
完成。此外,我提出的解决方案处理文件名中的空格


但是,仍然存在一个问题(您最初的方法中也存在这个问题)。假设使用参数
foo-foo.backup
调用脚本。由于参数是按顺序处理的,
foo
将被复制到
foo.backup
上,从而删除旧的备份文件。在此之后,脚本将创建一个
foo.backup.backup
,它将只包含原始
foo
的第二个副本。你必须考虑如何处理这种情况。

除了你的方法会失败之外,如果你的脚本通过一个包含空格的文件名,你的脚本就会自相矛盾:在
copy_file
中,你假设
filename
包含一组文件名(因为你要循环它们),再往下看时,执行一个
[-f“$FILENAME”]
,这意味着您假设
FILENAME
包含一个文件名。你必须下定决心,你的变量的内容是什么

现在,如何修复它:您似乎想要处理文件名列表,如果文件不存在,则发出错误消息。如果它存在,您希望创建一个备份副本,并编写一条消息说明您这样做了。因此,您需要循环传递给脚本的参数:

#!/bin/bash
for filename in "$@"
do
    cp -v "$filename" "$filename.backup"
done
检查是否存在由
cp
完成,复制时打印有意义的消息由
-v
完成。此外,我提出的解决方案处理文件名中的空格

但是,仍然存在一个问题(您最初的方法中也存在这个问题)。假设使用参数
foo-foo.backup
调用脚本。由于参数是按顺序处理的,
foo
将被复制到
foo.backup
上,从而删除旧的备份文件。在此之后,脚本将创建一个
foo.backup.backup
,它将只包含原始
foo
的第二个副本。你必须考虑如何处理这种情况

#!/bin/bash
for filename in "$@"
do
    cp -v "$filename" "$filename.backup"
done