从shell脚本的参数列表中删除最后一个参数(bash)

时间:2013-12-05 11:13:45

标签: bash shell argument-passing automator

这个问题涉及在automator osx中运行的bash脚本。我正在使用automator动作来获取和过滤来自finder的一堆文件引用。然后我通过自动机器操作将该文件夹的名称附加到该列表中。然后,Automator将这些参数提供给名为“run shell script”的操作。我不确定automator究竟是如何调用脚本的,但是当回显时,参数列表看起来像这样:echo "$@"

  

/ Volumes / G-Raid / Online / WAV_TEST / Testbok 50/01/01000 43-001.wav / Volumes / G-Raid / Online / WAV_TEST / Testbok 50/02/02000 43-002.wav / Volumes / G-Raid / Online / WAV_TEST / Testbok 50/03/03000 43-003.wav / Volumes / G-Raid / Online / WAV_TEST / Testbok 50

在这种情况下,指向3个文件和文件夹的路径。

在shell脚本中,我启动了一个名为ripcheckc *的应用程序,其中args从automator传递,减去列表中的最后一个参数(文件夹)。

我用它来删除最后一个参数:

_args=( "$@" )
unset _args[${#_args[@]}-1]

这是echo $_args

  

/ Volumes / G-Raid / Online / WAV_TEST / Testbok 50/01/01000 43-001.wav / Volumes / G-Raid / Online / WAV_TEST / Testbok 50/02/02000 43-002.wav / Volumes / G-Raid / Online / WAV_TEST / Testbok 50/03/03000 43-003.wav

与之前相同,但没有文件夹。

现在,如果我使用"$@"作为参数运行ripcheckc它可以工作(但由于参数列表中的最后一个路径,稍后会失败)如果我使用${_args[@]},应用程序将默默地中止。当我回显$@_args时,输出看起来完全相同,除了最后一个参数。

我的问题是 - 产生第一个有效输入的$ @和$ _args之间有什么区别?第二个没有?

*申请表为ripcheckc

我希望我的问题有道理。

编辑:解决了。

3 个答案:

答案 0 :(得分:25)

我之前使用过这个bash单行

set -- "${@:1:$(($#-1))}"

它将参数列表设置为当前参数列表,而不是最后一个参数。


工作原理:

  • $#是参数的数量
  • $((...))是一个算术表达式,因此$(($#-1))比参数的数量少一个。
  • ${variable:position:count}substring expression:它从位置开始从count中提取variable个字符。在special case其中variable@,这意味着参数列表,它从{{1}开始的列表中提取count 参数 }。对于第一个参数,positionposition1比之前计算出的参数数少一个。
  • count sets the argument list到给定的参数

因此最终结果是参数列表被替换为新列表,其中新列表是除最后一个参数之外的原始列表。

答案 1 :(得分:9)

您还可以使用

获取除最后一个参数以外的所有参数
"${@:0:$#}"
老实说,它有点粗略,因为它似乎是(ab)使用参数从1开始编号而不是0的事实。

更新:这仅适用于处理$@时出现的错误(最迟在4.1.2中修复)。它适用于3.2版。

答案 2 :(得分:8)

假设您已经拥有array,您可以说:

unset "array[${#array[@]}-1]"

例如,如果您的脚本包含:

array=( "$@" )
unset "array[${#array[@]}-1]"    # Removes last element -- also see: help unset
for i in "${array[@]}"; do
  echo "$i"
done

通过说:bash scriptname foo bar baz将返回:

来调用它
foo
bar