【问题标题】:Bash: using xargs/parallel arguments in function for variable substituionBash:在函数中使用 xargs/parallel 参数进行变量替换
【发布时间】:2016-06-11 23:26:15
【问题描述】:

我已经为这个 Bash 脚本苦苦挣扎了大约一周,试图做看似最简单的事情。我正在使用fswatch 监视给定文件夹并生成添加到其中的任何单个文件的文件名作为输出。该输出通过管道传送到xargs,然后运行一个函数,其中包含几个命令,这些命令使用fswatch/xargs 传递的文件名和变量/参数替换。

#!/bin/bash

compressor() {
    filepath="filepath"
    mkdir -m 777 /Users/lr/Desktop/Watch/${filepath##/}_PROCESSING
    mv ${filepath} /Users/lr/Desktop/Watch/${filepath##/}_PROCESSING
    /Applications/Compressor.app/Contents/MacOS/Compressor -computergroup "This Computer" -jobpath /Users/lr/Desktop/Watch/${filepath##/}_PROCESSING/${filepath##/} -settingpath /Users/lr/Documents/CONVERTHQTEST.cmprstng -locationpath /Users/lr/Desktop/Watch/${filepath##/}_PROCESSING/${filepath%.*}.mp4
}

export -f compressor

/usr/local/Cellar/fswatch/1.8.0/bin/fswatch -0 -v --event Created --event MovedTo /Users/lr/Desktop/Watch |
    xargs -0 -n1 -I'filepath' bash -c compressor 'filepath'

在最简单的配置中,我将输出通过管道传输到 xargs 并使用 xargs 使用参数替换运行程序,一切正常。然后我收到一个请求,让脚本为添加的每个文件创建一个新文件夹,将文件移动到该文件夹​​,然后运行命令。

使用多个命令似乎没有任何效果。我无法让xargs 将参数传递给函数,以便函数可以使用参数定义变量并在文件路径中进行变量替换。如果我在函数中执行xargs -I'filepath' command 'filepath' 然后filepath="filepath",我最终会以mkdir 创建一个名为filepath_PROCESSING 的文件,而不是替换来自fswatch 的参数。

如何使用xargs 将参数传递给函数?

【问题讨论】:

  • 我也试过这个:#!/bin/bash /usr/local/Cellar/fswatch/1.8.0/bin/fswatch -0 -v --event Created --event MovedTo /Users/leftright/Desktop/Watch | parallel -0 -n1 -q -x -v 'mkdir -m 777 /Users/leftright/Desktop/Watch/"{/.}"_PROCESSING/ \; mv "{}" /Users/leftright/Desktop/Watch/"{/.}"_PROCESSING/ \; /Applications/Compressor.app/Contents/MacOS/Compressor -computergroup "This Computer" -jobpath /Users/leftright/Desktop/Watch/"{/.}"_PROCESSING/"{/}" -settingpath /Users/leftright/Documents/CONVERTHQTEST.cmprstng -locationpath /Users/leftright/Desktop/Watch/"{/.}"_PROCESSING/"{/.}".mp4 \;'
  • 显然这不是很清晰;如果对问题很重要,则应通过编辑添加它,以便其他人可以阅读。

标签: macos bash xargs


【解决方案1】:

两件事:你误会how function arguments are passed。它们是位置参数(例如 1、2、3 等),因此您的函数可以这样定义:

compressor() {
    filepath="$1"
    # define a variable rather than including this 5 times
    process="/Users/lr/Desktop/Watch/${filepath#/}_PROCESSING"
    mkdir -m 777 "$process"
    mv "$filepath" "$process"
    /Applications/Compressor.app/Contents/MacOS/Compressor -computergroup "This Computer" -jobpath "$process/${filepath#/}" -settingpath /Users/lr/Documents/CONVERTHQTEST.cmprstng -locationpath "$process/${filepath%.*}.mp4"
}

然后,当您调用bash -c 时,它需要一个参数(请参阅下面的注释),但您传递了两个参数。尝试一些引号,它应该可以工作:

fswatch -0 -v --event Created --event MovedTo /Users/lr/Desktop/Watch |
    xargs -0 -n1 -I filepath bash -c 'compressor "filepath"'

[-c will] 处理完选项后从第一个非选项参数读取并执行命令,然后退出。任何剩余的参数都分配给位置参数,从 $0 开始。

Bash Reference Manual, Invoking Bash

显然我无法复制您的设置,但这里是 an MVCE,它在 bash 版本 3 和 4 中对我来说很好:

#!/bin/bash    
make_noise() {
    echo "$1" "$1" "$1" "$1"
}
export -f make_noise
echo "foo bar" | xargs -I {} bash -c "make_noise '{}'"

【讨论】:

  • 感谢您的帮助。现在使用xargsbash -c 我得到以下错误:bash: compressor: command not found。我在执行fswatchxargs 之前添加了export -f,但它似乎没有任何区别。当我用parallel 替换xargs 时,即使应用了-v 标志,我也没有收到任何反馈。是否有另一个组件可以让函数作为命令的参数工作?
  • 对我来说很好用;请参阅我对最小测试用例的编辑。
  • 稍作调整后,您的原始示例效果很好。我还没有尝试过并行。我现在唯一的问题是 fswatch 递归地监视子目录,所以脚本的原始设计创建了一个子目录循环。我将进行修改,以便将新文件发送到 fswatch 不监视的另一个文件夹。完成后我会发布完成的脚本。再次感谢!
【解决方案2】:

试试:

#!/bin/bash

compressor() {
    filepath="$1"
    mkdir -m 777 /Users/lr/Desktop/Watch/${filepath##/}_PROCESSING
    mv ${filepath} /Users/lr/Desktop/Watch/${filepath##/}_PROCESSING
    /Applications/Compressor.app/Contents/MacOS/Compressor -computergroup "This Computer" -jobpath /Users/lr/Desktop/Watch/${filepath##/}_PROCESSING/${filepath##/} -settingpath /Users/lr/Documents/CONVERTHQTEST.cmprstng -locationpath /Users/lr/Desktop/Watch/${filepath##/}_PROCESSING/${filepath%.*}.mp4
}

export -f compressor

/usr/local/Cellar/fswatch/1.8.0/bin/fswatch -0 -v --event Created --event MovedTo /Users/lr/Desktop/Watch |
    parallel -0 compressor

【讨论】:

    猜你喜欢
    • 2021-02-05
    • 1970-01-01
    • 2014-07-19
    • 2014-02-03
    • 2013-04-25
    • 1970-01-01
    • 1970-01-01
    • 2016-07-11
    • 2019-08-18
    相关资源
    最近更新 更多