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

从shell脚本(bash)的参数列表中删除最后一个参数,bash,shell,argument-passing,automator,Bash,Shell,Argument Passing,Automator,这个问题涉及在automator osx中运行的bash脚本。我使用自动机操作从查找器中获取并过滤一组文件引用。然后我将父文件夹的名称附加到该列表中,这也是通过一个自动机操作实现的。Automator然后将这些参数提供给一个名为“运行shell脚本”的操作。我不确定automator究竟是如何调用脚本的,但参数列表在与:echo“$@” /卷/G-Raid/Online/WAV_测试/Testbok 50/01/01000 43-001.WAV/Volumes/G-Raid/Online/WAV

这个问题涉及在automator osx中运行的bash脚本。我使用自动机操作从查找器中获取并过滤一组文件引用。然后我将父文件夹的名称附加到该列表中,这也是通过一个自动机操作实现的。Automator然后将这些参数提供给一个名为“运行shell脚本”的操作。我不确定automator究竟是如何调用脚本的,但参数列表在与:
echo“$@”

/卷/G-Raid/Online/WAV_测试/Testbok 50/01/01000 43-001.WAV/Volumes/G-Raid/Online/WAV_测试/Testbok 50/02/02000 43-002.WAV/Volumes/G-Raid/Online/WAV_测试/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$\u args:

/卷/G-Raid/Online/WAV_测试/Testbok 50/01/01000 43-001.WAV/Volumes/G-Raid/Online/WAV_测试/Testbok 50/02/02000 43-002.WAV/Volumes/G-Raid/Online/WAV_测试/Testbok 50/03/03000 43-003.WAV

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

现在,如果我使用
“$@”
作为参数运行ripcheckc,它会工作(但由于参数列表中的最后一条路径而失败),如果我使用
${u args[@]}
,应用程序将自动中止。当我回显
$@
\u args
时,除了最后一个参数外,输出看起来是相同的

我的问题是-使第一个输入有效而第二个输入无效的$@和$\参数之间有什么区别

*应用程序是

我希望我的问题有意义


编辑:已解决。

假设您已经有一个
数组
,您可以说:

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

除了最后一个论点外,你还可以用

"${@:0:$#}"
老实说,这有点粗略,因为它似乎是(ab)使用参数从1开始编号的事实,而不是0


更新:这只适用于处理
$@
中的错误(最新在4.1.2中修复)。它在3.2版中工作

我以前使用过这个
bash
一行程序

set -- "${@:1:$(($#-1))}"
它将参数列表设置为当前参数列表,减去最后一个参数


工作原理:

  • $#
    是参数的数量
  • $(…)
    是一个算术表达式,因此
    $($#-1))
    比参数数少一个
  • ${variable:position:count}
    是一个:它从
    变量
    的位置开始提取
    计数
    字符。在where
    变量
    @
    (即参数列表)中,它从
    位置开始的列表中提取
    计数
    参数。这里,对于第一个参数,
    position
    1
    ,而
    count
    比之前计算出的参数数少一个
  • 将--arg1…argn
    设置为给定参数

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

谢谢,这是摆脱最后一个参数的更好方法。我的问题是,$@与$array相比似乎有一些不同之处,后者将它限定为我要传递给的应用程序的有效输入。我就是搞不清楚它是什么。@user1047256请尝试将
${array[@]}
传递给您的应用程序。我尝试了您的建议,但仍然没有成功。仅供参考,我把尼克换成了诺丹福。:-)@诺丹福总是引用变量。下一个答案应该被接受,而不是这个答案。它有三倍的投票权。我用双引号解决了这个问题。像这样:ripcheckc“${u args[@]}”.Code“${:1:${}-1}”正是它使“$@”中的参数列表完整,而没有最后一个。对。粗略的部分使用0作为第一个参数,以避免从第二个参数中减去1。实际上,索引0包括正在执行的脚本的非参数路径(shell自动提供的值)。您没有避免减法1-最后一个参数仍然包括在内,您必须减法1。使用0只是向列表中添加一个(可能不是必需的)值。由于随后修复了一个错误,这在
bash
3.2中似乎有效。简单而优雅:我喜欢它。我使用了下面@chepner建议的一个变体来“删除”前两个参数,以便正确地生成一个子进程:spawnProc“${@:3:$#}”。诚然,这很神秘,但这是因为BASH的根源。虽然很优雅也很简单。我可以要求一个游戏一个游戏的游戏吗?@StevenLu我已经修改了答案,为你提供了一个解释。我希望有帮助。太好了!