Bash脚本更改目录并带参数执行命令

12

我正在尝试完成以下任务:编写一个名为changedir的shell脚本,它接受一个目录名称、一个命令名称和(可选的)一些额外参数。然后,脚本将进入指定的目录,并使用提供的参数执行指定的命令。

以下是一个示例:

$ sh changedir /etc ls -al

这将进入/etc目录并运行ls -al命令。

到目前为止,我有:

#!/bin/sh
directory=$1; shift
command=$1; shift
args=$1; shift
cd $directory
$command
如果我像这样运行上述代码 sh changedir /etc ls,它会更改并列出该目录。但是,如果我为 ls 添加参数,它不起作用。我需要做什么才能纠正它?
2个回答

20

你似乎忽略了命令的其余参数。

如果我理解正确,你需要像这样做:

#!/bin/sh
cd "$1"         # change to directory specified by arg 1
shift           # drop arg 1
cmd="$1"        # grab command from next argument
shift           # drop next argument
"$cmd" "$@"     # expand remaining arguments, retaining original word separations

一个更简单、更安全的变体是:

#!/bin/sh
cd "$1" && shift && "$@"

谢谢Charles...我在上面的最后一行中使用"$cmd" "$@"是正确的吗?这样可以使"arguments"可选,即如果我运行"./changedir /etc/ ls",它将正常工作,同时"./indir /etc/ ls -al"也将正常工作。 - frodo
@Frodo:是的,你是对的。"$@"更好,因为它保留了传递的参数。这就是我的意思,但不是我写下的! - CB Bailey

-1

由于一个命令可能有多个参数,我建议使用引号。就像这样:

sh changedir.sh /etc "ls -lsah"

如果你省略掉 'shift',你的代码会更易读:

directory=$1;
command=$2;
cd $directory
$command

或者简单地说

cd DIRECTORY_HERE; COMMAND_WITH_ARGS_HERE

1
这条路会导致疯狂。@Charles Bailey的方法可以更清晰地处理参数。 - Gordon Davisson
确实,处理更复杂的命令可能会很麻烦,但对于这里提到的简单情况应该足够了。而且,目录部分和命令部分之间的区别更加清晰明确,因为参数实际上属于命令本身,而没有自己的含义。 - dgasper

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接