たとえば、ファイルfoobar
があり、次のような場合、ファイルの内容が変更されている間に出力したいと思います。
magic_command foobar
現在のターミナルにはファイルの内容が表示され、waitが表示されます。わからない場合は、^ Cを押します。
次に、別の端末から私が行う場合:
echo asdf >> foobar
最初のターミナルには、元のファイルの内容に加えて、新しく追加された行が表示されます(もちろん、^ Cを押さなかった場合)。
tail command
と-f
を併用できます。
tail -f /var/log/syslog
リアルタイムのショーに最適なソリューションです。
1つの端末画面に収まる短いファイルを表示する場合、変更されるのはファイル全体である可能性があるため、watch
を使用できます。
watch cat example.txt
Every 2.0s: cat example.txt Sun Aug 3 15:25:20 2014
Some text
another line
デフォルトでは、オプションのヘッダーを含めて、ファイル全体が2秒ごとに表示されます。
オプション -d
(--differences
)は、前のバージョンの出力または最初のバージョンからの変更を強調表示します。
less
のフォローモードはtail -f
に似ています-開いているときにF
を押すだけです。
ファイルの変更を検出し、tail -f filename
以外のことを行う必要がある場合は、スクリプトでinotifywait
を使用して変更を検出し、それに基づいて動作しました。以下に使用例を示します。その他のイベント名とスイッチについては、man inotifywait
をご覧ください。 inotify-tools
などを介してSudo apt-get install inotify-tools
パッケージをインストールする必要がある場合があります。
次に、exec-on-change
というスクリプトの例を示します。
#!/bin/sh
# Detect when file named by param $1 changes.
# When it changes, do command specified by other params.
F=$1
shift
P="$*"
# Result of inotifywait is put in S so it doesn't echo
while S=$(inotifywait -eMODIFY $F 2>/dev/null)
do
# Remove printf if timestamps not wanted
printf "At %s: \n" "$(date)"
$P
done
2つのコンソールで次のようにコマンドを入力しました(A>はコンソールAのエントリを意味し、B>はコンソールBのエントリを意味します)。
A> rm t; touch t
B> ./exec-on-change t wc t
A> date >>t
A> date -R >>t
A> date -Ru >>t
A> cat t; rm t
cat t
からの次の出力は、コンソールAに表示されました。
Thu Aug 16 11:57:01 MDT 2012
Thu, 16 Aug 2012 11:57:04 -0600
Thu, 16 Aug 2012 17:57:07 +0000
exec-on-change
からの次の出力は、コンソールBに表示されました。
At Thu Aug 16 11:57:01 MDT 2012:
1 6 29 t
At Thu Aug 16 11:57:04 MDT 2012:
2 12 61 t
At Thu Aug 16 11:57:07 MDT 2012:
3 18 93 t
rm
をt
したときにexec-on-change
スクリプトが終了しました。
私には3つの解決策があります:
1)tail -f
は良いアイデアです
2)使用するtailf
もあります
) 3番目はbashスクリプトです。
#!/bin/bash
GAP=10 #How long to wait
LOGFILE=$1 #File to log to
if [ "$#" -ne "1" ]; then
echo "USAGE: `basename $0` <file with absolute path>"
exit 1
fi
#Get current long of the file
len=`wc -l $LOGFILE | awk '{ print $1 }'`
echo "Current size is $len lines."
while :
do
if [ -N $LOGFILE ]; then
echo "`date`: New Entries in $LOGFILE: "
newlen=`wc -l $LOGFILE | awk ' { print $1 }'`
newlines=`expr $newlen - $len`
tail -$newlines $LOGFILE
len=$newlen
fi
sleep $GAP
done
exit 0