【发布时间】:2014-10-21 18:12:14
【问题描述】:
我正在使用 Debian 的最小网络安装映像。这是我在第一次登录时启动用户进程和守护进程的脚本。它逐行读取由命令组成的文件,检查它们是否已经在运行,如果没有,则启动它们:
#!/bin/bash
## This script reads a list of user startup daemons and launches them after the first login
STAT=`who | grep "$USER" | wc -l` ## Get login count
if [ "$STAT" -eq 1 ] ; then ## If login shell
while IFS=' ' read line ## First attempt to separate fields fails
do
CMD=`echo "$line" | grep -v ^\#` ## Use non comment lines only
if [ -n "$CMD" ] ; then
eval set "$CMD" ## The actual field separation
APPID=$(pgrep "$1")&& ## Check if process $1 of $CMD is already active and launch it if not
(echo "$1 already active as "$APPID) || ("$@" 1>/dev/null&& echo "Started $1 as $(pgrep "$1")")
fi
done < ~/.scripts/daemons
echo "start-daemons: Finished"
else
echo "start-daemons: Not a login shell"
fi
命令文件~/.scripts/daemons如下所示:
## List of processes / daemons to start at user login
## <command> <argument1> <argument2> ..
mpd
pulseaudio -D
gpg-agent --daemon --enable-ssh-support --write-env-file /tmp/.gpg-agent-info
该脚本适用于mpd。但问题是,由命令和(多个)选项(因此,空格)组成的行不会被拆分为字段。将字段分隔符 IFS 设置为 ' ' 没有区别,我觉得这很奇怪。在这种情况下有什么问题?谢谢!
编辑:正如 alvits 所建议的,通过在 while 循环中评估 set $line 来进行字段分离提供了一种简单的解决方法。但是为什么read line一开始就没有分离呢?
【问题讨论】:
-
您可以通过ShellCheck 运行您的脚本,解决这些问题,然后编辑您的问题吗?此外,将
--添加到pgrep(即pgrep -- "$1")。不是 100% 确定我理解这个问题,但听起来可能是分词问题或某些命令将-解释为选项。 -
在
check_process()内插入这一行eval set $1作为第一条语句。使用eval很丑,但在你的情况下它是最简单的。