有人可以帮我编写一个简单的 bash 脚本来处理以下用法:
./application channels;message
eg: ./application channel1 channel2 channel3;this is a message
所以基本上是分隔符之前的任何内容;是由空格分隔的通道,以及 ; 之后的任何内容 是消息。
基本上,我想将这些中的每一个存储到一个变量中并将它们打印出来......
由于您需要一条消息和一个或多个通道,因此首先指定消息更有意义,然后假设其余参数是通道。就像是
#!/bin/bash
message="$1"
shift # Now each argument in $@ is a channel
然后您的脚本可以按如下方式运行
$ ./application "This is a message" channel1 channel2 channel3
虽然这是您通常处理所需参数的方式,但与使用-m
指定消息相比的一个缺点是更难判断用户是否忘记指定消息
# Is "channel1" the message, or did the user forget to specify one?
$ ./application channel1 channel2 channel3
对于实施-m
,我建议您参考Jonathan Leffler 的回答。
您可能想寻找另一种方式来分隔消息,因为分号会导致 bash 读取到分号并“认为这是命令的结尾”。然后 bash 将使用分号之前的参数运行您的程序。随后,它将寻找一个名为“this”的程序或内置程序,并提供“is”、“a”和“message”作为 this 的命令行参数。但是 bash 可能会回答“this: command not found”。有关更多信息,请查看bash 手册中的 ';'/分号运算符的含义。
你可能会做如下的事情
#!/bin/bash
message=""
outfiles=""
# Loop until all parameters are used up
# shift "eats" one argument at a time
# util there are no arguments left then $1 is a emtpy string
while [ "$1" != "" ]; do
if [ "$1" == "-m" ] # the message
then
shift #"eat one arugment then $1 is your message"
#you should check if there is a argument after "-m"
message=$1
else
outfiles="$outfiles $1"
fi
# Shift all the parameters down by one
shift
done
# put the message it the other arguments specified.
for i in $outfiles; do
echo $message > $i
done
该程序所做的是检查“-m”然后它将转移所有参数,因此您的参数减去一次并将此消息写入其他参数,例如 $./program.bash -m "Hello world" output1.txt ouput2.txt该程序将消息“Hello world”放入新创建或(小心)覆盖的文件 output1.txt output2.txt
while getopts m: opt
do
case "$opt" in
(m) message="$OPTARG";;
(*) echo "Usage: $0 [-m 'message'] [chan ...]" >&2; exit 1;;
esac
done
shift $(($OPTIND-1))
for channel in "$@"
do
whatever -y because -m "$message" $channel
done
那应该行得通。它使消息可选,并且不需要您指定任何渠道。您可以相当容易地添加更多选项(那些在字母后使用冒号指定参数的选项;那些不使用不带冒号的参数的选项)。您可以坚持$#
在两个循环之间大于 0(但使用消息必须更改以反映这一点)。您可以坚持传递一条消息(但也必须为此更改使用消息)。所以它继续; 你的选择很多。
如评论中所述:
请注意,这
;
是 shell 的命令分隔符。你必须写:
./application 'channels;message'
在分号周围加上引号或在它之前加上反斜杠。那不是很正统的用法。您可以使用更惯用的符号,例如:
./application -m "this is a message" channel1 channel2 channel3
上面的脚本相当准确地实现了这个建议。
我看到的唯一问题是,如果消息中有
"
字符怎么办。./application -m "this isn"t a message" channel1
ETC...
您需要了解 shell 元字符,其中包括"'`$;(
. 对于所有这些,您需要逃脱罪魁祸首:
./application -m 'He said, "Don'\''t do that!"' chan1
通常,在消息周围使用单引号;如果你有一个单引号要写,请输入'\''
。
./application -m 'He said, "This is a message."' chan1
./application -m "This isn't a message." chan2
./application -m 'He said, "This isn'\''t a message", but they disagreed." chan3
您可以使用剪切命令:
#!/bin/bash
variables=`echo $* | cut -d';' -f1`
message=`echo $* | cut -d';' -f2`
echo "variables: " $variables
echo "message: " $message
一定要\
-escape 分号:
$ ./application channels\;message
channels: channels
message: message