1

A quick google search says I could enable auto logout (for text consoles) by setting a TMOUT parameter. However, I discovered later that this would only work with the bash shell.

Is there a way I could set a timer for auto logout if my default shell was fish?

What is the purpose? Security, of course. I want it to lock when it's idle for 1 minute.

12
  • 1
    Thanks for reposting over here. Don't forget to delete or close the one on Stack Overflow. I have a couple of ideas that will hopefully work for you that I'll add soon on this question. Aug 2, 2021 at 15:30
  • 1
    Consider deleting your cross-post on SO. Cross-posting is discouraged.
    – Kusalananda
    Aug 2, 2021 at 16:51
  • 1
    Probably because it has an "answer" there. You can flag it yourself for a moderator and ask them to delete it, and they'll probably do it for you since the only "answer" there says "Fish doesn't have this feature". Alternatively, you can edit it there to mention that you reposted over here, with a link to this one. Aug 2, 2021 at 17:52
  • 1
    I finally got back here to add detail to the tmux answer, but I guess I'm still wondering something. In the comment on the (now deleted) Stack Overflow question, you mentioned that you don't necessarily trust everyone else in the vicinity. And I got the feeling that you were connecting to a server from a local client. But then wouldn't you be locking the client computer itself? Is it a situation where the other local users all share an account for some reason on the client? Aug 7, 2021 at 21:59
  • 1
    @NotTheDr01ds Welcome back, bro. As for the client computer, I'm the only who uses it + I already made my PC lock every 1 min. I wouldn't want anyone to miss with anything that belongs to me. I asked for an auto lock feature on the server side because I wanted a protection option for a situation when I'd forget myself logged into the server when I would access the server directly or from a random client.
    – CodingNoob
    Aug 9, 2021 at 15:03

2 Answers 2

3

While Fish itself doesn't include support for TMOUT directly, there are a few alternatives that might work for you. Given the fact that my two approaches are so radically different, I'm going to include them in two separate answers.

First (and not my preferred approach, but it's closest to the Bash functionality), depending on your Fish version:

Short answer:

Create a new file ~/.config/fish/conf.d/fish_tmout.fish:

function start_logout_timer --on-event fish_prompt
    # Allows $last_pid to work in a function
    status job-control full
    if set --query __fish_tmout_pid
        # Stop previous timer
        kill -- -$__fish_tmout_pid
    end
    # Start new timer
    FISH_PID=%self sh -c "sleep 60; kill -HUP $FISH_PID" &
    # Allows logout without warning of background jobs
    disown
    set -gx __fish_tmout_pid $last_pid
end

function stop_logout_timer --on-event fish_preexec
    if set --query __fish_tmout_pid
        kill -- -$__fish_tmout_pid
    end
    set --erase __fish_tmout_pid
end

Restart your shell and you should find that you are automatically logged out after 1 minute of no activity in the shell.

Compatibility: At least Fish 3.2.2 and later. Known to not work on 3.0.2 and earlier.

Minor caveat: You will always have an extra "defunct sh" hanging out when you do a ps.

Note: This does handle multiple shell instances running, since each shell is tracking its own PID and timer in a global (not universal) variable.

Explanation:

You can attempt to replicate that Bash functionality through other Fish features. But since (from your comment on Stack Overflow), you want this in order to secure the session from other people around you in case you forget to log out, you should be aware of the limitations of both this and the TMOUT option available in other shells. Namely, if you walk away while using any "full-screen" app that has control of the terminal (e.g. less, vim, or plenty of others), then it's not going to work. TMOUT is only handled when you leave Bash idle at the prompt.

Likewise, this approach has the same limitation. With that in mind ...

The Bash manual has this to say about TMOUT:

In an interactive shell, the value is interpreted as the number of seconds to wait for a line of input after issuing the primary prompt. Bash terminates after waiting for that number of seconds if a complete line of input does not arrive.

In Fish parlance, that would be either:

  • The time period between the display of two consecutive prompts
  • The time period between the display of a prompt and the user entering an interactive command

Which can be handled by Fish function hooks for:

  • fish_prompt
  • fish_preexec

So the script above:

  • Starts an auto-logout timer (via sleep) when the prompt is displayed (fish_prompt)
  • Stops that timer (by killing the subprocess owning the timer and logout) when either the next prompt is displayed (fish_prompt) or a command is entered (fish_preexec).
  • Logs out of the shell (via SIGHUP) when the timer expires without being killed
4
  • Wow. I'm amazed at the level of the details and the in-depth analysis. I really didn't know it was this complicated. We need more intelligent and helpful people like you in this world. Thank you very very very much for your time and help on this matter. I really appreciate it.
    – CodingNoob
    Aug 2, 2021 at 17:41
  • 1
    Well thank you, and I think I often make it sound more complicated than it is with my (perhaps overly detailed) analysis. Fish is kind of a good example of the "80-20" rule -- Fish implements 80% of the functionality of other shells in a way that is much easier and cleaner than those shells (the big reason I moved from Zsh to Fish), but then there's that 20% that isn't implemented out-of-the-box, but can (with enough thought and knowledge of Fish) be done with other features. Aug 2, 2021 at 17:57
  • Yeah. There were some commands that didn't work for me (when I was a beginner). For example, variables are handled differently in fish. Took me a while to understand it.
    – CodingNoob
    Aug 3, 2021 at 3:54
  • I chose this as a "solution" since it does indeed answer the question and it works properly. As for Debian users, let them wait until they would get a proper updated version of fish. Thank you for your cooperation.
    – CodingNoob
    Aug 24, 2021 at 2:00
3

Another option for "securing the shell when inactive" is to use tmux, possibly in conjunction with vlock, assuming they are available on the server in question or you have permission to install them.

Assuming those are installed and in place, edit your ~/.tmux.conf and add the following:

set -g lock-after-time 60
set -g lock-command vlock

or ...

set -g lock-after-time 60
set -g lock-command "tmux kill-session"

That will lock or kill the entire Tmux session (all panes) after 60 seconds of inactivity. While I don't see this in the Tmux doc, inactivity in this case seems to be defined by "lack of keypress". In my testing, on-screen output from commands (such as a tail -f) do not seem to stop the inactivity-timer.

This is more secure than the TMOUT alternative, since it also works when you are running an interactive command like vi or less.

Note that in order to make this truly secure, tmux needs to be running as the top-level PID in your ssh session or terminal. There are a couple of ways to do this:

  • If you are connecting to the server via an ssh client (and it sounded like this might be the case), then just specify tmux as the RemoteCommand. The way to do this might vary depending on your client (e.g. Putty), but for a standard command-line client, you would execute something like:

    > ssh user@server tmux #or
    > ssh -o "RemoteCommand=tmux" user@server
    
  • Or add the RemoteCommand=tmux to your ~/.ssh/config for that server

  • Or, if you want to start Tmux manually after connection to the server, or potentially in your ~/.bash_profile (although be careful with this). Then use exec tmux so that tmux replaces the parent shell. When exiting or disconnecting from tmux, you'll be logged out immediately (or returned to a higher-level process, only if there was one), rather than the shell that you started it from.

3
  • Yup, this one works. Here is a GIF. However, this answer is indeed helpful but doesn't answer the original question. It also requires requires tmux & vlock. Also, it "locks" the terminal. Is there a way to make it "logout"?
    – CodingNoob
    Aug 24, 2021 at 0:35
  • BTW, I added tmux in /etc/fish/config.fish so that it runs automatically with the shell. (for both a local & remote security). Thanks for this answer though, it adds more option/way to achieve what the question asks for. I like the details you have posted. Thank you very much.
    – CodingNoob
    Aug 24, 2021 at 0:38
  • 1
    @CodingNoob Good to hear it's working for you. Yes, we can make it "logout". Adding that to the answer now. Aug 24, 2021 at 1:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.