'service' は予期しない結果をもたらします。 grep`

'service' は予期しない結果をもたらします。 grep`
$ sudo service --status-all | fgrep -e 'bluetooth'
 [ ? ]  alsa-utils
 [ ? ]  binfmt-support
 [ + ]  bluetooth
 [ ? ]  cpufrequtils
 [ ? ]  cryptdisks
 [ ? ]  cryptdisks-early
 [ ? ]  hdparm
 [ ? ]  hwclock.sh
 [ ? ]  kmod
 [ ? ]  loadcpufreq
 [ ? ]  networking
 [ ? ]  plymouth
 [ ? ]  plymouth-log
 [ ? ]  pppd-dns
 [ ? ]  udev-finish
 [ ? ]  virtualbox-guest-x11
$ sudo service bluetooth stop
[ ok ] Stopping bluetooth: /usr/sbin/bluetoothd.
$ sudo service --status-all | fgrep -e 'bluetooth'
 [ ? ]  alsa-utils
 [ ? ]  binfmt-support
 [ - ]  bluetooth
 [ ? ]  cpufrequtils
 [ ? ]  cryptdisks
 [ ? ]  cryptdisks-early
 [ ? ]  hdparm
 [ ? ]  hwclock.sh
 [ ? ]  kmod
 [ ? ]  loadcpufreq
 [ ? ]  networking
 [ ? ]  plymouth
 [ ? ]  plymouth-log
 [ ? ]  pppd-dns
 [ ? ]  udev-finish
 [ ? ]  virtualbox-guest-x11

service | grep各出力セットでは、1行だけがパターンに一致しますが、なぜ1つ以上の出力行が表示されるのですかgrep?この行の冒頭にどのような(悪い)魔法がありますか[?]?それとも何か抜けましたか?

FWIW、私は走っています。

$ date
Tue Nov 28 20:51:46 MST 2017
$ uname -rsv
Linux 3.16.0-4-amd64 #1 SMP Debian 3.16.43-2+deb8u5 (2017-09-19)
$ lsb_release -ds
LMDE 2 Betsy
$ cat /etc/debian_version
8.9
$ gcc --version | head -n 1
gcc (Debian 4.9.2-10) 4.9.2

答え1

私の考えでは、@Sundeepが正しいです。

serviceこの動作を引き起こすリダイレクトがあるかどうかを確認するためにスクリプトを見てください。

if ! is_ignored_file "${SERVICE}" \
    && [ -x "${SERVICEDIR}/${SERVICE}" ]; then
    out=$(env -i LANG="$LANG" LANGUAGE="$LANGUAGE" LC_CTYPE="$LC_CTYPE" LC_NUMERIC="$LC_NUMERIC" LC_TIME="$LC_TIME" LC_COLLATE="$LC_COLLATE" LC_MONETARY="$LC_MONETARY" LC_MESSAGES="$LC_MESSAGES" LC_PAPER="$LC_PAPER" LC_NAME="$LC_NAME" LC_ADDRESS="$LC_ADDRESS" LC_TELEPHONE="$LC_TELEPHONE" LC_MEASUREMENT="$LC_MEASUREMENT" LC_IDENTIFICATION="$LC_IDENTIFICATION" LC_ALL="$LC_ALL" PATH="$PATH" TERM="$TERM" "$SERVICEDIR/$SERVICE" status 2>&1)
    retval=$?
    if echo "$out" | egrep -iq "usage:"; then
        #printf " %s %-60s %s\n" "[?]" "$SERVICE:" "unknown" 1>&2
        echo " [ ? ]  $SERVICE" 1>&2          #<-------------------HERE
        continue
    else
    if [ "$retval" = "0" -a -n "$out" ]; then
        #printf " %s %-60s %s\n" "[+]" "$SERVICE:" "running"
        echo " [ + ]  $SERVICE"
        continue
    else
        #printf " %s %-60s %s\n" "[-]" "$SERVICE:" "NOT running"
        echo " [ - ]  $SERVICE"
        continue
    fi
fi

リダイレクトはエラー条件(サービスが呼び出しをサポートしていないstatus)のためであるため、表示される出力は[ ? ]「juju」ですが、実際にはgrepをバイパスするリダイレクトです。

コマンドラインでテストしてみてください...

~$ echo "banana" | grep bluetooth       #nothing echoed
~$ echo "banana" 1>&2 | grep bluetooth  #bingo, get a banana
banana

関連情報