0

有人可以帮我编写一个简单的 bash 脚本来处理以下用法:

./application channels;message

eg:  ./application channel1 channel2 channel3;this is a message

所以基本上是分隔符之前的任何内容;是由空格分隔的通道,以及 ; 之后的任何内容 是消息。

基本上,我想将这些中的每一个存储到一个变量中并将它们打印出来......

4

4 回答 4

2

由于您需要一条消息和一个或多个通道,因此首先指定消息更有意义,然后假设其余参数是通道。就像是

#!/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 的回答

于 2013-02-18T23:03:12.740 回答
1

您可能想寻找另一种方式来分隔消息,因为分号会导致 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

于 2013-02-18T22:50:16.333 回答
0
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" channel1ETC...

您需要了解 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
于 2013-02-18T23:01:52.913 回答
0

您可以使用剪切命令:

#!/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
于 2013-02-19T00:09:38.977 回答