63

I tried tailing two files using the option:

tail -0f file1.log -0f file2.log

In Linux I see an error "tail : can process only one file at a time".

In AIX I see the error as "Invalid options".

This works fine when I use:

tail -f file1 -f file 2

in Linux but not in AIX.

I want to be able to tail multiple files using -0f or -f in AIX/Linux

multitail is not recognized in either of these OS.

1
  • Have you tried to use screen to create two different sessions? You should be able to use tail on both screens? Also, tmux can do the job as well if you have it installed.
    – ryekayo
    Aug 7, 2014 at 15:25

8 Answers 8

55

What about:

tail -f file1 & tail -f file2

Or prefixing each line with the name of the file:

tail -f file1 | sed 's/^/file1: /' &
tail -f file2 | sed 's/^/file2: /'

To follow all the files whose name match a pattern, you could implement the tail -f (which reads from the file every second continuously) with a zsh script like:

#! /bin/zsh -
zmodload zsh/stat
zmodload zsh/zselect
zmodload zsh/system
set -o extendedglob

typeset -A tracked
typeset -F SECONDS=0

pattern=${1?}; shift

drain() {
  while sysread -s 65536 -i $1 -o 1; do
    continue
  done
}

for ((t = 1; ; t++)); do
  typeset -A still_there
  still_there=()
  for file in $^@/$~pattern(#q-.NoN); do
    stat -H stat -- $file || continue
    inode=$stat[device]:$stat[inode]
    if
      (($+tracked[$inode])) ||
        { exec {fd}< $file && tracked[$inode]=$fd; }
    then
      still_there[$inode]=
    fi
  done
  for inode fd in ${(kv)tracked}; do
    drain $fd
    if ! (($+still_there[$inode])); then
      exec {fd}<&-
      unset "tracked[$inode]"
    fi
  done
  ((t <= SECONDS)) || zselect -t $((((t - SECONDS) * 100) | 0))
done

Then for instance, to follow all the text files in the current directory recursively:

that-script '**/*.txt' .
4
  • 1
    any reason to prefer the sed way over the & way?
    – gilad905
    Aug 14, 2019 at 13:57
  • 1
    @giladmayani I'm just experimenting with this but the problem with the & way that I found is that if you wrap it in a script you will get ghost processes that don't quit. Oct 31, 2019 at 17:11
  • Doesn't tail accept multiple files and regex? Oct 6 at 19:40
  • @JustinGoldberg POSIX tail takes only one file. I'm not sure what tail would do with a regex. Oct 6 at 20:06
42

In OSX and Linux, using

tail -f <file1> <file2>

works great for me. Another nice thing is that it has the following output:

==> /srv/www/my-app/shared/log/nginx.access.log <==
things from log 1

==> /srv/www/my-app/shared/log/nginx.error.log <==
things from log 2

==> /srv/www/my-app/shared/log/nginx.access.log <==
new things from log 1

to help you recognize which output is from which log.

1
  • 8
    add q to supress the headers
    – Karl Pokus
    Dec 28, 2018 at 14:09
18

tail multiple files is extended by GNU tail version. With AIX, you don't have GNU tail, so you can't do it. You can use multitail instead.

You can install multitail in both Linux and AIX.

  • With AIX, you can download package here.

  • In Linux, multitail is often in repo, so you can install it easily using distro package manager:

    • In Debian/Ubuntu: apt-get install multitail
    • In Centos/Fedora: yum install multitail
2
  • 2
    Multitail works nice and syntax is simple: multitail -i path/to/file1 -i path/to/file2
    – The Onin
    Mar 25, 2019 at 1:07
  • Nice find! Any idea how to redirect the output of multitail? I only managed to use it in interactive mode... Jan 29, 2021 at 16:04
8

The following thing works fine to output things on std out

tail -f file1 & tail -f file2

I wanted to pipe the output to another process. In above case & was making the part before it run in the background and only second part was being piped to process

so I used

tail -f file1 file2 | process

@Stéphane your answer is perfect, but just mentioning my use case which has a little twist.

2
  • 2
    The point is that tail -f file1 file2 doesn't work on AIX where tail accepts only one filename. You can do (tail -f file1 & tail -f file2) | process to redirect the stdout of both tails to the pipe to process. Jun 9, 2016 at 8:46
  • This worked for me tail -100f log1.log & tail -100f log2.log
    – Gagan
    Jan 4, 2022 at 17:51
1

I will provide a code snippet using tmux that can give you two different windows you can use to tail both files simultaneously:

tmux new-window -a -n Tail
tmux new-session -d -s Tail -n SSH0 -d
tmux selectp -t Tail

#This is tmux interactions with the user (colors of the tabs used, hot keys, etc.)
tmux bind-key -n M-Left previous-window -t WinSplit
tmux bind-key -n M-Right next-window -t WinSplit
tmux set-window-option -g monitor-activity on
tmux set -g visual-activity on
tmux set-window-option -g window-status-current-bg blue
tmux set-window-option -g window-status-fg red
tmux set -g pane-border-fg yellow
tmux set -g pane-active-border-bg red
tmux set -g message-fg yellow
tmux set -g message-bg red
tmux set -g message-attr bright
tmux set -g status-left "#[fg=red]#S"

#Names two seperate windows
tmux new-window -n tail1 -t Tail
tmux new-window -n tail2 -t Tail

#Now this will allow you to automatically run tail when this tmux script is run
tmux send-keys -t Tail:0 'tail -f file1.log' C-m
tmux send-keys -t Tail:1 'tail -f file2.log' C-m

UPDATE: Using screen can also attach/detach multiple sessions so you can run tail multiple times as well. I can suggest doing this:

screen -s Tail_Server1.log

Next you would want to hold CTRL+A+D to dettach without killing the sessions and then next:

screen -s Tail_Server2.log

Both will run two seperate screens, I would refer to screen --help so you can adjust it to how you want both screens to work on your terminal.

0
0

Following works for me on SunOS 5.10.

$ tail -f file1.log &
$ tail -f file2.log &
$ 

Both tails will run in background. The changes to files will be thrown to stdout. Moreover you can run any command in between just by hitting enter.

1
  • 1
    ...but that creates two processes that you have to kill and mixes STDOUT with foreground output.
    – mpowered
    Aug 20, 2017 at 20:05
0

Use the following oneliner:

while true; do cat /path/to/numerous/folders/and/files/*/*.txt | grep "some filter" | tail -n 10; sleep 1; done

Every 1 second, the script will print 10 last lines of the filtered stream.

To break the loop, press CtrlC.

0

In Linux and OSX, supposed the files are in a different locations like these:

  • logs/nginx/nginx-access.log
  • logs/nginx/nginx-error.log
  • logs/php/php-error.log
  • logs/php/php-fpm-error.log

With the above logs, while inside the logs/ directory, you can use this command:

tail -f {php/php-{,fpm-}error,nginx/nginx-{access,error}}.log

Or you can use a wildcard to tail everything inside the logs/ directory

tail -f {nginx,php}/*.log
0

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .