【问题标题】:shell script for subversion files用于颠覆文件的 shell 脚本
【发布时间】:2013-05-24 21:52:22
【问题描述】:

脚本不适用于“?”案子。当我直接在命令行中运行时......工作正常但在脚本中无法运行“?”健康)状况。

  svn st svn_promote_WP
  M       svn_promote_WP\Code\Environment\DEV\properties\build.properties
  M       svn_promote_WP\Code\Environment\RT\properties\build.properties
  ?       svn_promote_WP\props.pl

这是我的脚本:

 #!/usr/bin/sh

 meta_data=(`svn st svn_promote_WP | cut -c1`)
 meta_files=(`svn st svn_promote_WP | awk '$1~/^[AMD?]$/{for(i=2;i<=NF;i++)print $i}'`)

 for index in ${!meta_data[*]}
 do
    if [ ${meta_data[$index]} = "?" ]; then
    echo "${meta_files[$index]} need to be added"
    elif [ ${meta_data[$index]} = "M" ]; then
    echo "${meta_files[$index]} are modified"
    fi
 done

输出:

 svn_promote_WP\Code\Environment\DEV\properties\build.properties are modified
 svn_promote_WP\Code\Environment\RT\properties\build.properties are modified

期望的输出:

  svn_promote_WP\Code\Environment\DEV\properties\build.properties are modified
  svn_promote_WP\Code\Environment\RT\properties\build.properties are modified
  svn_promote_WP\props.pl need to be added

更新了更多细节 - 在命令行上运行时的结果:

$ svn st svn_promote_WP | cut -c1
M
M
?


$ svn st svn_promote_WP | awk '$1~/^[AMD?]$/{for(i=2;i<=NF;i++)print $i}'
svn_promote_WP\Code\Environment\DEV\properties\build.properties
svn_promote_WP\Code\Environment\RT\properties\build.properties
svn_promote_WP\props.pl

【问题讨论】:

    标签: bash shell awk cut if-statement


    【解决方案1】:

    这是一个引用问题,但并非无关紧要。首先,您没有在测试中将${meta_data[$index]} 括在双引号中。其次,? 已经在数组分配中展开。不幸的是,第二个问题不能通过添加双引号来解决;你需要一些更棘手的东西,即

    set -f
    meta_data=(`svn st svn_promote_WP | cut -c1`)
    meta_files=(`svn st svn_promote_WP | awk '$1~/^[AMD?]$/{for(i=2;i<=NF;i++)print $i}'`)
    set +f
    

    这是什么原因?在您的原始代码中,bash 对svn st svn_promote_WP | cut -c1 的输出执行两个操作:每当遇到空格时,它将其拆分为单个单词,并扩展通配符(= 文件名扩展)。因此,如果当前目录中有文件z,则? 将替换为z`svn st svn_promote_WP | cut -c1` 周围的双引号将防止分词和文件名扩展,因此 svn st svn_promote_WP | cut -c1 的整个输出未修改地分配给第一个数组元素。但是你需要一些不同的东西,即“保持分词,但防止文件名扩展”。为了获得这种效果,您必须省略双引号并使用禁用文件名扩展的 shell 选项,即-f。赋值完成后,执行set +f即可恢复正常的shell行为。

    【讨论】:

      【解决方案2】:

      引用变量的用法:

      if [ "${meta_data[$index]}" = "?" ]; then
      echo "${meta_files[$index]} need to be added"
      elif [ "${meta_data[$index]}" = "M" ]; then
      echo "${meta_files[$index]} are modified"
      fi
      

      【讨论】:

      • 没有用。我只对修改过的文件而不是测试条件得到相同的结果。
      • 是的,实际上,我无法重现任何错误行为。所以也许你想更多地了解这件事。但是,决不能省略引号。
      • 我觉得奇怪的是,您使用了一个名为 /usr/bin/sh 的 shell,但随后提出了 bash 语法的代码(并且还用 bash 标记了问题)。
      • 循环中的echo "${meta_data[$index]}" 输出什么?那么"${meta_files[$index]}"呢?
      • @Alfe 通配符的文件名扩展已经发生在数组分配中。请尝试以下操作:A=($(echo 'x' '*' 'y')); printf '%s\n' "${A[@]}"。问题是不能像A=("$(echo 'x' '*' 'y')"); printf '%s\n' "${A[@]}" 那样使用双引号来解决这个问题;所以必须使用set -f 明确关闭文件名扩展。 (当然,? 只会被扩展,前提是当前目录中至少有一个文件名仅包含一个字符。)
      猜你喜欢
      • 2020-06-28
      • 2011-01-28
      • 1970-01-01
      • 1970-01-01
      • 2018-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多