1
\$\begingroup\$

(running Ubuntu 16.04.3) I created small script with tasks I do every time I upgrade/change Ubuntu version. One of the tasks is to write script to file, this is actual written file:

#!/bin/bash

if [ "$1" == "eno1" ]; then
 case "$2" in
  up) nmcli radio wifi off
      notify-send "cable network detected, turning WIFI off" -u low -t 10;;
  down) nmcli radio wifi on
      notify-send "cable network unplugged, turning WIFI on" -u low -t 10;;
  esac
fi

And this is how I write it from another script:

MY_FILE="/etc/NetworkManager/dispatcher.d/99-wlan"
ni="$(nmcli dev status | grep ethernet | awk '{ print $1 }')"
echo -e '#!/bin/bash\n\nif [ "$1" == "'"$ni"'" ]; then\n case "$2" in\n'\
  ' up) nmcli radio wifi off\n      notify-send "cable network detected, turning WIFI off" --urgency critical --expire-time 6;;\n'\
  ' down) nmcli radio wifi on\n      notify-send "cable network unplugged, turning WIFI on" --urgency critical --expire-time 6;;\n'\
  ' esac\nfi' | sudo tee -a "$MY_FILE" > /dev/null
sudo chmod +x "$MY_FILE"

My question is, if syntax I'm using is correct. When I check it with shellcheck utility, it complaints about first line:

echo -e '#!/bin/bash\n\nif [ "$1" == "'"$ni"'" ]; then\n case "$2" in\n'\
        ^-- SC2016: Expressions don't expand in single quotes, use double quotes for that.
                                            ^-- SC2016: Expressions don't expand in single quotes, use double quotes for that.

can I ignore this warnings or is there a better how to write it ? Keep in mind I'm using variable $ni when I'm writing to file.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Is that the complete script? With no action and no diagnostic if $1 is something other than eno1? \$\endgroup\$ Commented Oct 13, 2017 at 9:28
  • \$\begingroup\$ yes, it's complete. eno1 is my only network adapter for cable network. script works only if there is cable network adapter, and is disconnected, --> then turn WIFI on, when connected --> then turn off. \$\endgroup\$
    – mauek unak
    Commented Oct 13, 2017 at 11:01

2 Answers 2

1
\$\begingroup\$

I agree with @TobySpeight's review, and have only minor things to add on top.

I find it tedious and error-prone to escape symbols in here-documents. So I prefer the <<"EOF" syntax which makes the here-document content verbatim, so no escaping is necessary. To work around the goal to embed a variable, I would split the content to two here-documents, one where values can be expanded, and one that's verbatim:

cat <<EOF >"$SCRIPT"
#!/bin/bash

ni="$(nmcli dev status | awk '/ethernet/ { print $1 }')"

EOF

cat <<"EOF" >>"$SCRIPT"
if [ "$1" == "$ni" ]; then
    case "$2" in
        up)
            nmcli radio wifi off
            notify-send "cable network detected, turning WIFI off" --urgency critical --expire-time 6
            ;;
        down)
            nmcli radio wifi on
            notify-send "cable network unplugged, turning WIFI on" --urgency critical --expire-time 6
            ;;
    esac
fi
EOF

Notice that I replaced | grep ethernet | awk '{ print $1 }' with | awk '/ethernet/ { print $1 }' which is the same thing, but shorter, and using one less process in the pipeline.

\$\endgroup\$
3
\$\begingroup\$

Instead of embedding sudo in the script, simply require that it be run as root, either by simply failing (using set -e), or with a friendly check such as

die() { echo "$@" >&2; exit 1; }

test $UID = 0 || die "$0: you need to be a superuser!"

That echo can be made much easier to read, and can avoid the non-portable -e option, by using a here-document:

cat <<END >"$MY_FILE"
#!/bin/bash
if [ "\$1" == "$ni" ]; then
    case "\$2" in
        up)
            nmcli radio wifi off
            notify-send "cable network detected, turning WIFI off" --urgency critical --expire-time 6
            ;;
        down)
            nmcli radio wifi on
            notify-send "cable network unplugged, turning WIFI on" --urgency critical --expire-time 6
            ;;
    esac
fi
END

(I'm assuming you meant tee rather than tee -a in your code).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.