带有 dry-run 和 exec 选项的 Bash 函数

带有 dry-run 和 exec 选项的 Bash 函数

我正在编写一个 bash 函数来运行rsync,可以使用--dry-run选项和--exec选项。需要一些批评改进和额外检查。

--dry-run对于用户指定和可能没有多大意义--exec。无论如何我都会简单地使用 --dry-run 。

已开始进行以下设置。

调用以下内容

filetr-archive -n -s bkscan -d temp

运行命令

rsync -av --progress --dry-run --log-file=temp/bkscan.log bkscan temp

这使得文件temp/bkscan.log的内容是

2021/07/19 23:55:15 [19947] building file list
2021/07/19 23:55:15 [19947] cd+++++++++ bkscan/
2021/07/19 23:55:15 [19947] sent 273 bytes  received 56 bytes  658.00 bytes/sec
2021/07/19 23:55:15 [19947] total size is 108,837,826  speedup is 330,814.06 (DRY RUN)

但是,rsync也会产生以下内容,但永远不会被保存。rsync终端上显示的输出有用吗?我还可以存储信息。但我想知道我怎样才能做到这一点。

  bkscan temp
sending incremental file list
bkscan/
bkscan/BkScan.aux
bkscan/BkScan.cp
bkscan/BkScan.fn
bkscan/BkScan.ky
bkscan/BkScan.log
bkscan/BkScan.pdf
bkscan/BkScan.pg
bkscan/BkScan.texi
bkscan/BkScan.texi~
bkscan/BkScan.tp
bkscan/BkScan.vr
bkscan/BookScan.texi~

sent 273 bytes  received 56 bytes  658.00 bytes/sec
total size is 108,837,826  speedup is 330,814.06 (DRY RUN)

filetr-archive ()
{
  # Process command line options
  shortopts="nel:s:d:"
  longopts="dry-run,exec,log:,source:,destin:"
  opts=$(getopt -o "$shortopts" -l "$longopts"  \
        -n "$(basename $0)" -- "$@")
  if [ $? -eq 0 ]; then
    eval "set -- ${opts}"
    while [ $# -gt 0 ]; do
      case "$1" in
      -n|--dry-run)
        shift 1
        local -r dryrun=1
        ;;
      -e|--exec)
        shift 1
        local -r exec=1
        ;;
      -l|--log)
        local logfl=$2
        shift 2
        ;;
      -s|--source)
        local source=$2
        shift 2
        ;;
      -d|--destin)
        local destin=$2
        shift 2
        ;;
      --)
        shift;  break  ;;
      esac
    done
  else
    shorthelp=1 # getopt returned (and reported) an error.
  fi

  if (( filetr_dryrun == 1 )); then 

    echo "rsync -av --progress --log-file=$logfl --dry-run"
    echo "  $source $destin"
    rsync -av --progress --log-file=$logfl --dry-run $source $destin

  elif (( filetr_exec == 1 )); then
      
    # use rsync archive option -a (equivalent to -rlptgoD)
    echo "rsync -av --progress --log-file=$logfl $source $destin"
    # rsync -av --progress --log-file=$logfl $source $destin

  else

    echo "rsync -av --progress --log-file=$logfl $source $destin"
      
  fi

答案1

rsync -av --progress --log-file=$logfl --dry-run $source $destin

需要双引号,即--log-file="$logfl" --dry-run "$source" "$destin".看什么时候需要双引号?http://mywiki.wooledge.org/WordSplitting

local logfl=$2

这可能也应该使用双引号。简单的赋值(logfl=$2不带local或其他任何内容)是不需要它们的情况之一,但是对于localexportreadonly,则不是那么明确。只需将引号放在那里即可防止出现任何问题。

  if (( filetr_dryrun == 1 )); then 
    ...
    rsync -av --progress --log-file=$logfl --dry-run $source $destin
  elif (( filetr_exec == 1 )); then
    ...
    rsync -av --progress --log-file=$logfl $source $destin

您在此处复制代码,所有这些-av, --progress, $source,$destin在两个分支中都是相同的。最好避免这种情况,并且由于您正在运行 Bash,因此您可以将参数收集到数组中,请参阅:有条件地将参数传递给脚本

filetr-archive ()

破折号在 Bash 和 Zsh 中作为函数名称的一部分,但在 Ksh 或 Dash 中则不然,因此为了可移植性,使用下划线可能更有意义。当然,无论如何你都在使用非 POSIX 的东西(( .. )),所以你可能至少想有意识地忽略 Dash。

相关内容