Bash:在函数中使用xargs / parallel参数进行变量替换

时间:2016-02-29 02:03:02

标签: macos bash xargs

我一直在努力使用这个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将参数传递给函数?

2 个答案:

答案 0 :(得分:0)

两件事:你误解了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将在处理选项后从第一个非选项参数中读取并执行命令,然后退出。任何剩余的参数都分配给位置参数,从$ 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 '{}'"

答案 1 :(得分:0)

尝试:

#!/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