有没有办法知道文件是否已被复制?

有没有办法知道文件是否已被复制?

我正在使用 Ubuntu 22.04,我正在制作一个 bash 程序(脚本)来在启动、关闭和/或重新启动时运行脚本。这些事情很敏感,如果做得不好,可能会对用户/电脑造成危险,所以我做了多项检查,比如标志/参数是否正确解析、参数是否有效、文件是否有效等。

当所有检查都完成后,我有以下几行:

cp -iv $source_file /etc/init.d/custom_script_$file_name

如果这不是用户想要的,我正在使用 -i 标志来避免覆盖脚本,但我不知道如何(如果有办法)知道用户是否提示是或否,因为如果用户说否,脚本应该停止。

有什么办法可以做到这一点或者我应该采取一种解决方法吗?

答案1

通过比较文件的内容

如果成功将文件复制到不同的文件名,则两个文件的内容应该相同...并且考虑到这些脚本文件不太可能在复制过程后立即或立即改变内容,那么...

您可以使用cmp复制过程结束后立即与源文件进行比较(原来的) 文件复制到目标 (复制) 文件,内容如下:

#!/bin/bash

cp -iv "$source_file" "/etc/init.d/custom_script_$file_name"

if cmp -s "$source_file" "/etc/init.d/custom_script_$file_name"; then
  # Both files are identical
  # Do things based on that here:

else
  # The files are different
  exit 1
fi

或者用更简单的一行代码来类似:

cmp -s orig_file dest_file && echo "files are identical"

和:

cmp -s orig_file dest_file || echo "files are different"

Bycp的退出状态

cp -i在较新版本上) IE

$ cp --version
cp (GNU coreutils) 9.4
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Torbjörn Granlund, David MacKenzie, and Jim Meyering.

和更新版本)应该返回不成功错误用户1输入的代码(no以及其他错误,例如No such file or directory请记住这一点)...因此,您可以在脚本中监听该事件,例如,trap并定义一个函数来对其执行操作,如下所示:

#!/bin/bash

check_status () 
{ 
    local status=$?
    (( status == 1 )) && exit $status
}

trap check_status ERR

# Your "cp -i ..." command below

# Unset the signal trap so the rest of the script gets excluded from that trap
trap - ERR

...并且应该终止(出口) 您的脚本是否需要用户输入no确认cp -i

注意而上述内容可能是对多个文件操作进行全面控制/报告的首选,cp -i因为它可以进行扩展,例如,您知道哪些文件被用户接受,哪些文件被忽略,例如:

$ cat copy.sh
#!/bin/bash

check_status () 
{ 
    local status=$?
    (( status == 1 )) && notcopied+=( "$f" )
}

trap check_status ERR

for f in file*; do
  cp -iv "$f" dir/
  done
  
if (( ${#notcopied[@]} > 0 )); then
  printf '%s\n' "The user answered NO to these files:"
  printf '%s\n' "${notcopied[@]}"
  exit 0
fi
$
$ ls file*
file  file1  file.log
$ ls dir/
file  file1  file.log
$
$ ./copy.sh
cp: overwrite 'dir/file'? n
cp: overwrite 'dir/file1'? n
cp: overwrite 'dir/file.log'? y
'file.log' -> 'dir/file.log'
The user answered NO to these files:
file
file1

然而,对于单个文件复制操作来说,这可能是一个过度的操作,因为您可以在命令之后直接评估退出状态,cp -i例如:

#!/bin/bash

cp -iv "$source_file" "/etc/init.d/custom_script_$file_name" || exit 1

... 以以外的1任何退出状态退出。cp -i0

或者例如:

#!/bin/bash

cp -iv "$source_file" "/etc/init.d/custom_script_$file_name"
(( $? == 1 )) && exit 1

... 以1错误状态退出,并且仅当退出状态为 时才1退出cp -i

或者:

#!/bin/bash

cp -iv "$source_file" "/etc/init.d/custom_script_$file_name"
if (( $? == 0 )); then
  # The user answered "yes" and the copy was successful
  # Do stuff here:
  
else
  # The user probably answered "No" and/or the copy failed
  # exit here:
  exit 0
fi

... 成功则执行操作cp -i,否则退出。

其他遇到任何错误时退出脚本的更简单直接的方法是:

#!/bin/bash

.
.
.
# Start exit on error
trap exit ERR

# Your command(s)
cp -iv "$source_file" "/etc/init.d/custom_script_$file_name"

# End exit on error
trap - ERR
.
.
.

或者类似地set -e

#!/bin/bash

.
.
.
# Start exit on error
set -e

# Your command(s)
cp -iv "$source_file" "/etc/init.d/custom_script_$file_name"

# End exit on error
set +e
.
.
.

...当然,您可以结合这两种方法,即检查/处理错误/退出状态并比较文件的内容。

相关内容