Bash は for ループから最初の文字を削除します。

Bash は for ループから最初の文字を削除します。

次のコードスニペットがあります。

#!/bin/bash
IFS='\r\n'
vconsole="pts"
for entry in $(last -n 10)
do
        if [ -z $entry ]
        then
                continue
        fi
        if [ "$( echo $entry | grep -o 'pts')" == "$vconsole" ]
        then
                echo $entry
        fi
done

実行すると、次のような結果が得られます。

oot     pts/0        85.XXX.XXX.138   F
oot     pts/0        85.XXX.XXX.138   Mo
oot     pts/1        85.XXX.XXX.138   Tue Ja
oot     pts/0        85.XXX.XXX.138   Tue Ja

私は次のことを期待しています:

root     pts/0        85.XXX.XXX.138   Fri Jan 15 11:19   still logged in
root     pts/0        85.XXX.XXX.138   Mon Jan 11 10:12 - 10:43  (00:31)
root     pts/1        85.XXX.XXX.138   Tue Jan  5 14:30 - 14:39  (00:08)
root     pts/0        85.XXX.XXX.138   Tue Jan  5 13:29 - 14:39  (01:10)

最初のキャラクターが切り取られたのはなぜですか?そして、なぜ結末がランダムに見えるのですか?

私はこれを実行していますcentos-release-7-9.2009.1.el7.centos.x86_64

ベストアンサー1

IFS='\r\n'

「root」と「Fri」にあるものと「Mon」と「Jan」にあるものが区切り文字として機能するように設定されIFSます。バックスラッシュを実際の制御文字CRおよびLRにエスケープするANSI C引用符を使用しようとしています。つまり、次のようになります。<backslash><letter r><backslash><letter n>rn$'...'

IFS=$'\r\n'

以下も使用できます。

if [[ $entry = *pts* ]]; then...

文字列を見つけ、その文字列とこのユーザー名の一部であるecho | grepフィールドとも一致します。pts

これを防ぐには、次のようにします。

#!/bin/bash
last -n 10 | while read -r line; do
    read -r  user term whatever <<< "$line"
    if [[ $term = *pts* ]]; then
        echo "$line"
    fi
done

おすすめ記事