我有一个 bash 脚本,它会进行一些系统更改,涉及以“http”开头的 URL 地址列表,并且我正在尝试为其编写一个 GUI。
我坚持以下最后一部分:
changes="$(cat /home/$USER/.updates.log | grep http)"
if [ "$changes" != 0 ]; then
zenity --question --text "Changes found in:\n$changes\n\nWould you like to update now?"
if [ $? = 0 ]
then
# password
sudo_password="$(gksudo --print-pass --description 'MyScript' -- : 2>/dev/null)"
# check for null entry or cancellation
if [[ ${?} != 0 || -z ${sudo_password} ]]
then
exit 4
fi
if ! sudo -kSp '' [ 1 ] <<<"${sudo_password}" 2>/dev/null
then
exit 4
fi
# notify
notify-send "Applying updates..." -i gtk-dialog-info -t 1000 -u normal &
# proceed to update
cuser="${SUDO_USER:-$USER}"
sudo -Sp '' sudo /usr/local/bin/MyScript <<<"${sudo_password}"
# option to view log
new_update="$(cat /home/$USER/.updates.log | grep 'MyScript completed at ' | awk -F ' at ' '{print $2}')"
zenity --question --text "MyScript updated at $new_update\n\nWould you like to view the log file now?"
if [ $? = 0 ]
then
# display log
zenity --text-info --filename=/home/$USER/.updates.log --width 680 --height 680
fi
fi
fi
事实上,对我来说棘手的部分似乎在这里:
if [ "$changes" != 0 ]; then
如果该文件不包含以“http”开头的行,我只想显示一条消息,例如“未找到更新;正在退出...”,但这只是在 zenity 问题对话框中创建一个空行。看来我需要修改这一行,并在“else”下添加另一个命令,但我只是不知道如何以及在哪里......
答案1
我无法测试脚本的其余部分,因为我没有必要的数据,甚至不知道它的作用,但这一行肯定是错误的:
changes="$(cat /home/$USER/.updates.log | grep http)"
这将节省输出grep
中的命令$changes
,不是找到字符串的次数,而是返回的实际行数。例如:
$ cat file
one http
two http
three http
$ changes=$(cat file | grep http)
$ echo "$changes"
one http two http three http
正如您在上面看到的,$changes
只是文件中的每个匹配行连接成一个变量。你想要的是这样的(cat
顺便说一句,不需要grep
可以将文件名作为输入):
$ changes=$(grep -c http file)
$ echo $changes
3
该-c
开关使grep
打印匹配行的数量而不是行本身。或者,您可以传递输出来wc -l
计算行数:
changes=$(grep http file | wc -l)
任一都可以,您现在可以检查是否$changes
大于 0:
if [ "$changes" -gt 0 ]]; then
...
fi
如果要显示更改,请使用原始方法,但不要将其与 0 进行比较。而是使用-z
检查变量是否为空:
changes=$(grep http /home/$USER/.updates.log)
## If $changes is empty
if [ -z "$changes" ]
then
notify-send "Found no updates; exiting..." -i gtk-dialog-info -t 1000 -u normal &
exit
else
zenity --question --text "Changes found in:\n$changes\n\nWould you like to update now?"
...
fi
答案2
关于问题在哪里要放置其余条件,提示是始终遵守缩进,这肯定会使任务变得更容易:)
我还没有测试过它(我可能是错的),但我会尝试这样的开始:
changes="$(cat /home/$USER/.updates.log | grep http)"
if [ "$changes" != 0 ]; then
zenity --question --text "Changes found in:\n<i>$changes</i>\n\nWould you like to update now?"
if [ $? = 0 ]; then
## password
sudo_password="$(gksudo --print-pass --description 'MyScript' -- : 2>/dev/null)"
## check for null entry or cancellation
if [[ ${?} != 0 || -z ${sudo_password} ]]; then
exit 4
fi
if ! sudo -kSp '' [ 1 ] <<<"${sudo_password}" 2>/dev/null; then
exit 4
fi
## notify
notify-send "Applying updates..." -i gtk-dialog-info -t 1000 -u normal &
## proceed to update
cuser="${SUDO_USER:-$USER}"
sudo -Sp '' sudo /usr/local/bin/MyScript <<<"${sudo_password}"
## option to view log
new_update="$(cat /home/$USER/.updates.log | grep 'MyScript completed at ' | awk -F ' at ' '{print $2}')"
zenity --question --text "MyScript updated at <b><i>$new_update</i></b>\n \nWould you like to view the log file now?"
if [ $? = 0 ]; then
## display log
zenity --text-info --filename=/home/$USER/.updates.log --width 680 --height 680
fi
fi
## Here is where you can choose what to do if there are no results
else
zenity --text-info "No updates found; exiting..."
fi