参数传递问题求解

sh/bash/dash/ksh/zsh等Shell脚本
头像
自由建客
帖子: 13468
注册时间: 2008-07-30 23:21
系统: Debian stable AMD64

参数传递问题求解

#1

帖子 自由建客 » 2012-03-03 15:00

一个 bash 脚本,名为 notify-send2。
敲入以下命令测试

代码: 全选

notify-send2 -u critical "hello world"
结果总是不对。关键在 su 时的参数传递。
-------------------------------------------------------------------------------

代码: 全选

su "$user" -c "notify-send \"$*\"" 
su "$user" -c "notify-send $@"
这两种压根不对,提示
Missing argument for -u
这个应该是 notify-send 的输出,后面的 critical "hello world" 断掉了。

代码: 全选

>0< urd$ notify-send -u
Missing argument for -u

>1< urd$
-------------------------------------------------------------------------------

代码: 全选

su "$user" -c "notify-send '""$@""'"
更严重,提示
critical: -c: line 0: unexpected EOF while looking for matching `''
critical: -c: line 1: syntax error: unexpected end of file

-------------------------------------------------------------------------------

代码: 全选

su "$user" -c bash <<<"notify-send $@"
命令可行,但实际结果是 hello 和 world 分开了,导致 hello 成了标题 world 成了内容。
上次由 自由建客 在 2012-03-03 15:09,总共编辑 2 次。
头像
自由建客
帖子: 13468
注册时间: 2008-07-30 23:21
系统: Debian stable AMD64

Re: 参数传递问题求解

#2

帖子 自由建客 » 2012-03-03 15:05

附完整脚本

代码: 全选

#!/bin/bash

sendmsg()
{
	local IFS="=$IFS"
	while read line
	do
		read key value <<<"$line"
		value="${value#\'}"
		value="${value%\'}"
		case "$key" in
			unix-user)
				uid=$value
				;;
			active)
				active=$value
				;;
			x11-display)
				display=$value
				;;
			Session*:)
				[ "$active" != "TRUE" ] && continue
				export DISPLAY="$display"
				user=`sed -n 's/^\([^:]\+\):[^:]\+:'"$uid"':.*/\1/p' /etc/passwd`
				su "$user" -c "notify-send \"$*\""    # 问题就在这行
				;;
		esac
	done <<<"`ck-list-sessions | sed -n '/^Session\|\tunix-user =\|\tactive =\|\tx11-display =/p;$a\Session:\'`"
}

if [ "`id -u`" -eq 0 ]; then
	sendmsg "$@"
else
	exec notify-send "$@"
fi
上次由 自由建客 在 2012-03-03 15:21,总共编辑 2 次。
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: 参数传递问题求解

#3

帖子 tusooa » 2012-03-03 15:06

完了,id穿越了。 :em06

代码: 全选

] ls -ld //
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: 参数传递问题求解

#4

帖子 tusooa » 2012-03-03 15:06

建议你以后cp .com的链接的时候,去掉sid那一串。

代码: 全选

] ls -ld //
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: 参数传递问题求解

#5

帖子 tusooa » 2012-03-03 15:11

首先,建议不要用su.
sudo env DISPLAY=:0 bash -c 'notify-send "$@"' "$@"
行不

吾写的,删掉干啥。

代码: 全选

] ls -ld //
头像
自由建客
帖子: 13468
注册时间: 2008-07-30 23:21
系统: Debian stable AMD64

Re: 参数传递问题求解

#6

帖子 自由建客 » 2012-03-03 15:15

tusooa, 抱歉,我以为是那堆水鬼干的。
su 是必须的,这段脚本的目的就是能让守护进程给活动桌面发送消息。
http://forum.ubuntu.org.cn/viewtopic.php?f=21&t=365871
viewtopic.php?f=21&t=365871
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: 参数传递问题求解

#7

帖子 tusooa » 2012-03-03 15:34

那就sudo -u "$user"这样的。

代码: 全选

sudo -u "$user" bash -c 'notify-send "$@"' "$@"
su的会很麻烦的。

代码: 全选

] ls -ld //
头像
自由建客
帖子: 13468
注册时间: 2008-07-30 23:21
系统: Debian stable AMD64

Re: 参数传递问题求解

#8

帖子 自由建客 » 2012-03-03 15:44

tusooa, 没看懂你那命令,但结果不对。
critical 成了标题,而不是紧急程度了。
sudo -u "$user" bash -c 'echo "$@"' "$@"
得到的只有
critical hello world
前面的 -u 没了

我现在暂时用临时文件搞定。

代码: 全选

				cmdfile=`mktemp`
				chmod 755 "$cmdfile"
				echo -n "notify-send " >"$cmdfile"
				for arg in "$@"
				do
					echo -n "'$arg' " >>"$cmdfile"
				done
				su "$user" -c "bash $cmdfile"
				rm -f "$cmdfile"
头像
自由建客
帖子: 13468
注册时间: 2008-07-30 23:21
系统: Debian stable AMD64

Re: 参数传递问题求解

#9

帖子 自由建客 » 2012-03-03 15:52

TMD!我干吗要用临时文件!

代码: 全选

				cmd="notify-send "
				for arg in "$@"
				do
					cmd="$cmd '$arg'"
				done
				su "$user" -c bash <<<"$cmd"
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: 参数传递问题求解

#10

帖子 tusooa » 2012-03-03 16:02

哦。那是参数给bash当opt了额

代码: 全选

sudo -u "$user" bash -c 'notify-send "$@"' -- "$@"

代码: 全选

] ls -ld //
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: 参数传递问题求解

#11

帖子 tusooa » 2012-03-03 16:03

自由建客 写了:TMD!我干吗要用临时文件!

代码: 全选

				cmd="notify-send "
				for arg in "$@"
				do
					cmd="$cmd '$arg'"
				done
				su "$user" -c bash <<<"$cmd"
你这样也不大好的。要是arg里有单引号,就完了。

代码: 全选

] ls -ld //
头像
自由建客
帖子: 13468
注册时间: 2008-07-30 23:21
系统: Debian stable AMD64

Re: 参数传递问题求解

#12

帖子 自由建客 » 2012-03-03 16:14

tusooa, 这下好了

代码: 全选

					cmd="$cmd \"`echo "$arg" | sed 's/"/\\\\"/g'`\""
头像
自由建客
帖子: 13468
注册时间: 2008-07-30 23:21
系统: Debian stable AMD64

Re: 参数传递问题求解

#13

帖子 自由建客 » 2012-03-03 16:24

还是 sudo 好,还省得我要把 uid 转成 user
头像
lilydjwg
论坛版主
帖子: 4258
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: 参数传递问题求解

#14

帖子 lilydjwg » 2012-03-03 18:08

要是我就用 Python 了。
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: 参数传递问题求解

#15

帖子 tusooa » 2012-03-04 0:21

要是吾就用perl了。

代码: 全选

] ls -ld //
回复