次のコードスニペットがあります。
#!/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>
r
n
$'...'
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