198

I like the watch command, but it has its limitations.

I'm curious to know whether I could mimic the functionality of watch with less. I'm mainly looking for the ability to scroll through my directory as it dynamically gets modified via a running script.

1
  • I am looking for tail -f foo.log | grep bar, and to be able to dynamically change the grep command with restarting the tail/grep pipeline. Commented Sep 13, 2018 at 23:56

12 Answers 12

184

In less, you can type F (Shift+F) to keep reading at the end of a file (like tail -f); you can type :e and a file name to view a different file, but unfortunately, if you enter the name of the current file, less doesn't reload the file. However there's a trick to make it re-read the current file, suggested by sabgenton: type :e and enter the name of a non-existent file; that causes less to display an error message and then reload the current file.

If you're looking for an alternative to watch ls, here are a few:

  • Modern file managers (e.g. Nautilus, Thunar, Konqueror, Dolphin, Finder) refresh views in real time.
  • Emacs doesn't have real-time refresh, but with auto-revert-mode, it will reload the file or directory every 5 seconds (the delay is configurable).
  • Although w3m is primarily a web browser, it makes a passable directory and text file viewer. Press R to reload the (local) URL.
17
  • 16
    For me :e randomnamejkdlfjldf fails to load the non-existent filename then reloads back to the current file :D
    – sabgenton
    Commented Mar 18, 2016 at 10:36
  • 1
    @sabgenton Thanks, I didn't know that. That's a great trick. I added it to my answer, but you could post it as an answer of your own (which I hope Zaid would accept). Commented Mar 18, 2016 at 16:14
  • 2
    @CMCDragonkai No, less +F only watches for appended content. Use :e nonexistentfile to re-read completely changed input. Commented Apr 19, 2016 at 11:08
  • 4
    @PaulWagland No, R doesn't reliably refresh the file. It refreshes the screen, and wipes some input buffers, but it doesn't actually reload data from the file in all circumstances (only if the file is large? I didn't dig deeply into the code). Commented Apr 20, 2017 at 9:53
  • 2
    I wish I could give you a +1 for every time I forget about this and find myself here again. :D Commented Jun 16, 2017 at 1:17
84

Shift+F will make less similar to the command tail -f. That is, it gets refreshed if more data is appended to the file.

5
  • 17
    Note that this only works for appends. If lines are removed or edited in-place, less won't show those changes. Commented Nov 30, 2016 at 1:26
  • 2
    How do I stop following mode and re-enter scrollable mode?
    – Tom Hale
    Commented Feb 9, 2017 at 12:18
  • 4
    <kbd>Ctrl+C</kbd>
    – balki
    Commented Feb 9, 2017 at 20:41
  • 2
    balki My experience is that this kills the command piping the data if you are using $COMMAND | less. I wonder if there is a nice way around this? You can do stuff like $COMMAND > /tmp/file & less /tmp/file but that's not very nice.
    – Att Righ
    Commented Jul 27, 2018 at 11:13
  • 1
    @AttRigh I never killed my command (however i read logs of running commands this way, i don't pipe into less, technically)
    – jena
    Commented Jan 11, 2019 at 13:48
57

Simply type:

less +F filename

This emulates pressing "F" within the editor.

2
  • 3
    Thanks; added the alias alias check="less +F" to my .bashrc.
    – Luke Davis
    Commented Jul 27, 2017 at 21:31
  • 1
    Same as <kbd>Shift+F</kbd> when already in less, for followers...
    – rogerdpack
    Commented Apr 7, 2021 at 17:19
30

man pages can be very informative. Don't be intimidated by them. Among everything else, man less says you can use the R command to:

   R      Repaint the screen, discarding any buffered input.  Useful if the file is changing while it is being viewed.

(I realize this question is over 6 years old, but it comes up on google searches, so I'm not the only one that clicked the link to get here.)

8
  • 12
    This repaints the screen in case it was disrupted by output from another program. It doesn't consistently reload the file. I haven't dug deeply into the code to see what it does, experimentally short files don't get reloaded. I am definitely not intimidated by man pages and I say this description is poorly worded: “repaint” does not convey that input is re-read, and the actual behavior does not quite fit “useful if the file is changing” (maybe it's a bug? I don't know since I don't know what the command is supposed to do).. Commented Apr 20, 2017 at 9:51
  • I'm no expert, and haven't read less's source code either, but what it does is forget what it already knows about the file & reloads it, refreshing its output based on the input it reloads. The question reads "Is there a way to dynamically refresh the less command?" If I had read the question's explanation more thoroughly before answering, I might not have answered, since they go on to say they want "to scroll through my directory as it dynamically gets modified via a running script." less wouldn't be the right command for that. Commented Apr 21, 2017 at 3:58
  • Works fine for me, even when using files 3 bytes long. I can't imagine why it wouldn't work for larger files too.
    – Addison
    Commented Mar 22, 2018 at 3:51
  • 3
    Great! For me it works for both short and long files. I just noticed two possible problems: 1. less did not reopen the file using its filename - i.e. when the inode of the file changed (like in overwriting the file using mv) then the old file content stayed (probably the old inode was reread) --- 2. The first displayed line probably starts at the same byte offset as in the original file content. So when the line lengths change the first displayed line could be incomplete and the displayed lines could move up / down. Commented Sep 13, 2018 at 11:27
  • 3
    R doesn't always work. See unix.stackexchange.com/questions/4351/…
    – wisbucky
    Commented Apr 17, 2019 at 19:18
12

R for repaint does not always reload the file.[1]

A workaround that always reloads the file is to press hq, which will open the Help page, then quit. It has a side effect of forcing the file to reload.


[1] Here are some examples of situations that R do and do not reload:

  • > and >> changes: DO get reloaded
  • sed -i, gEdit, TextEdit: DO NOT get reloaded
  • On Linux, vi changes: DO get reloaded
  • On Mac, vi changes: DO NOT get reloaded

I believe the difference comes down to whether the inode changes (you can check with ls -i foo.txt). If the inode changes, then R will not work.

1
  • I really like the hq hack, but note that if you happen to be viewing the end of a file that gets shorter, less will fail out. (Really, if you happen to be seeked anywhere past the end of the new file) With one more key, you can avoid that crash: ghq.
    – carver
    Commented Dec 10, 2019 at 1:09
7

I normally just type G to tail the output on a one-time basis. I find it especially helpful over a a network file system like CIFS.

5
  • This is more of an on-demand refresh of the file opened with less. In addition to jumping to the end of the file, it also reloads the file if it has changed.
    – jorb
    Commented Jun 6, 2017 at 13:23
  • 1
    Thanks. First time it didn't refresh for me, but now it seems to work properly. In the man it's not written that it refreshes the file. man less: 'G or > or ESC-> Go to line N in the file, default the end of the file.' I delete my old wrong comments here, sorry for them. Commented Jun 8, 2017 at 13:56
  • 2
    BTW, what do you call a 'one-time basis'? The maintainer of less, Mark Nudelman, replied the following: "The G command does not normally force a re-read of the file like the R command does. It may seem do that if the end of the file has not yet been read when G is invoked, so that jumping to the end of the file must read the data there for the first time. For example, if you jump to the end with G, then jump back to the beginning with 1G, then another program modifies the data at the end of the file (without changing the length), " (cont) Commented Jun 12, 2017 at 20:14
  • (cont) "then you jump to the end again with G, you will not see the modified data. But if you don't jump to the end and back to the beginning, then the first time you execute the G command it must read the data there for the first time, and of course it will see any modifications that have happened since less was first invoked. " Commented Jun 12, 2017 at 20:14
  • 1
    In this case I mentioned it being a one-time refresh as opposed to a dynamic refresh, which is part of what the original question is asking.
    – jorb
    Commented Jun 12, 2017 at 20:31
5

The "F" key when running less will do a "follow" similar to tail -f, but I'm not sure if that will achieve what you're looking for here.

1

You could pipe it to tail -f instead, it would result in you following the output. You'd be losing the ability to move (scroll) through your output though.

1

You can use vim to read the file then add the following mapping to your .vimrc file and you can easily reload a file with ,r:

let mapleader = ","
nnoremap <leader>r :edit <CR>

Note if you edited the file already, vim will complain. Just change to

let mapleader = ","
nnoremap <leader>r :edit! <CR>

To ignore changes.

1
  • They'll have to pry vim from your cold, dead hands. The context of the question is about less, but as someone with monomaniacal tendencies myself, I sympathise!
    – Benjamin R
    Commented Oct 26, 2018 at 16:05
1

I worked around this problem using a shell script that auto-reloads less on exit:

while true; do less -K file.txt || exit; done

With this script, I can hit q to reload the file, and CTRL+C to exit back to the bash shell. The CTRL+C behavior is enabled via the -K option. Your last search term will be preserved.

This can be further refactored by using the colon (:) to create an empty expression, via do : ...

while less -K file.txt; do : ; done

Drawbacks

The current viewing position will always be rest to line 0.

Practical Example using mintty

In my windows (GitBash) environment I set up a script that opens a new terminal window (mintty) for less-viewing a file:

lesswin() { mintty bash -c "while less -K \"$@\"; do : ; done;" & }
0

I just found this thread like anyone else. I would like to add the solution of when you are already at the end of the file, using 'g' followed by 'G' will force a refresh of the file.

I ended up making a macro button for this in my terminal program (SecureCRT). The macro is simply 'gG'.

0

You could use the inotify-tools to watch for directory changes and rerun ls every time a file is written to:

inotifywait -mqe CLOSE_WRITE <directory-path> | while read; do clear; ls <directory-path>; done

inotifywait can also be used to watch an overwritten file:

inotifywait -mqe MODIFY <file-path> | while read; do clear; cat <file-path>; done

You must log in to answer this question.

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