将括号作为脚本参数传递给macOs defaults命令

时间:2017-07-22 17:49:00

标签: bash macos quoting

我正在为我的dotFiles写一个设置脚本。如果找到我的笔记本电脑,此脚本的一部分将获得一些基本的联系信息以显示在锁定屏幕上。在此阶段,消息看起来像这样

“如果找到,请拨打000-000-0000或发送电子邮件至my@email.com”

这是我为此写的函数:

function collectInfo() {
    echo "We'll set a lock screen message for anyone who finds your laptop."
    echo "Please enter a valid phone number: "
    read phonenumber
    echo "Please enter a valid email: "
    read contactemail
    msg="If found, please call "$phonenumber" or email "$contactemail
    sudo defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText $msg
    if [ $? -eq 0 ]; then
        echo "Data entered"
        defaults read /Library/Preferences/com.apple.loginwindow LoginwindowText
    else
        echo "There was an issue with your input.  Please try again"
        collectInfo
    fi
}

如果我尝试将括号传递给loginwindow设置,我遇到了麻烦,例如(000)000-0000。我可以回显$ msg,它似乎正在创建字符串就好了。有没有办法传递一个带括号的字符串作为参数,还是我必须使用sed来敲除它们?

1 个答案:

答案 0 :(得分:1)

这里有两个混淆因素:

  • 未能在_get_line_num_last () { local attempts=0 local line=0 while true; do # Greps the last two lines that can be considered history records local lines="$(grep -anE '^: [0-9]{10}:[0-9]*?;' ~/.zsh_history | \ tail -n $((2 + attempts)) | head -2)" local previous_line="$(echo "$lines" | head -1)" # Gets the line number of the line being tested local line_attempt=$(echo "$lines" | tail -1 | cut -d':' -f1 | tr -d '\n') # If the previous (possible) history records ends with `\`, then the # _current_ one is part of a multiline command; try again. # Probably. Unless it was in turn in the middle of a multi-line # command. And that's why the last line should be saved. if [[ $line_attempt -ne $HISTORY_LAST_LINE ]] && \ [[ $previous_line == *"\\" ]] && [[ $attempts -eq 0 ]]; then ((attempts+=1)) else line=$line_attempt break fi done echo "$line" } precmd() { local line_num_last="$(_get_line_num_last)" local date_part="$(gawk "NR == $line_num_last {print;}" ~/.zsh_history | cut -c 3-12)" local fmt_date="$(date -d @${date_part} +'%Y-%m-%d %H:%M:%S')" # I use awk itself to split the _first_ line only at the first `;` local command_part="$(gawk " NR == $line_num_last { pivot = match(\$0, \";\"); print substr(\$0, pivot+1); } NR > $line_num_last { print; }" ~/.zsh_history)" if [ "$command_part" != "$PERSISTENT_HISTORY_LAST" ] then echo "${fmt_date} | ${command_part}" >> ~/.persistent_history export PERSISTENT_HISTORY_LAST="$command_part" export HISTORY_LAST_LINE=$((1 + $(wc -l < ~/.zsh_history))) fi } 附近加上引号将其拆分为多个单独的参数。
  • $msg开头并以(结尾的参数由)解析为数组,因此defaults被解析为包含一个元素的数组。

要确保将您的内容解析为字符串,您可以使用文字引号开始和结束它:

(000)

外部双引号(defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText "'$msg'" )由shell处理,以确保整个消息只作为一个参数传递;内部单引号(")将传递给'并指导它如何解析值。