Is it possible to set "permanent variable" in shell? For example, when I log in I want to print message "Hello user, this is your xxx log in"

The number of logins would be stored in permanent variable, and each time it would be incremented by script e.g

echo "Hello Mr. This is your $number log in"

The next log in would print the incremented variable and increment it again.

How could I set a variable like that?

  • 3
    You need to write that number into a file and read from file every time you login, in your .profile or .bashrc or equivalent. – MelBurslan Mar 3 '16 at 20:15
  • 2
    That's literally what files are for. – PSkocik Mar 3 '16 at 20:22
  • you also have to think about what you consider to be a "login". You can login at the console, or over the network (e.g. via ssh). Most terminal apps can be configured so that each tab can be treated as a login shell. So what you consider to be a login and what (various parts of) the system considers to be a login may be completely different. – cas Mar 3 '16 at 21:30

You can't. However, you can use various hacks to do it, for example creating a file in some folder each time a user logs in, or adding a line to some file each time a user logs in. These would be easy to implement, but inefficient in long run. A much more efficient operation would be writing a number to a file, and changing it. You would, however, have to be sure that the file is structured as you want and that the number is where you expect it to be. Since these are hacks, they aren't perfect(malicious user can modify these), but could suffice for your problem.

You can count lines with wc -l

| improve this answer | |

I'd write:

echo "Hello Mr. This is your $number log in"
echo $((number+1)) > "$file"
| improve this answer | |
  • Does this properly handle malicious file contents? e.g. 7; rm -r / – wizzwizz4 Mar 26 '19 at 18:14
  • I think it's fine: the contents of the number variable are not evaluated in the echo command (double quotes) and in arithmetic context there will be a syntax error. – glenn jackman Mar 26 '19 at 18:26

Matthew Rock's answer is nice as are the other ones but like Matthew points out then the user can change these numbers. One way to circumvent that is to use PAM.

I would put the following line in /etc/pam.d/login

session optional pam_exec.so /usr/local/bin/{someshellscript}.sh

And in /usr/local/bin/{someshellscript}.sh you can use variables like $PAM_USER which gives the username. Then in the shellscript you can access a file that is not writable (and perhaps not readable, depends on what you want) to the users and keep tabs on all the users and how often they have logged in, in that file. I leave the writing of that script as an exercise to the reader ;-)

| improve this answer | |

Here's one possible hack; add the following lines to your $HOME/.bash_profile (since you tagged bash):

printf "Hello Mr. This is your %d log in\n" $((NLOGINS + 1))
sed -i 's/^NLOGINS=.*/NLOGINS='$((NLOGINS + 1))'/' $HOME/.bash_profile

Each time you log in, you'll get the printed message and then it will self-update the .bash_profile with the new NLOGINS count.

| improve this answer | |

Look at this post https://unix.stackexchange.com/a/350163

Permanent variables using kv-bash functions:

1) Download kv-bash file from github:

git clone https://github.com/damphat/kv-bash.git
cp -ar ./kv-bash/kv-bash /usr/local
chmod +x /usr/local/kv-bash

# Put this line in .bash_profile (optional)
source kv-bash

2) Try

#let try create/modify/delete variable
kvset myEmail john@example.com
kvset myCommand "Very Long Long Long String"

#read the varible
kvget myEmail

#you can also use in another script with $(kvget myEmail)
echo $(kvget myEmail)

#delete variable
kvdel myEmail
| improve this answer | |

With zsh, you can use the $mapfile special associative array that gives you access to the content of a file as a variable (beware of concurrent access).

#! /bin/zsh -
zmodload zsh/mapfile
echo "Hello Mr. This is your $((++mapfile[$HOME/.number]))th log in"

fish has so-called Universal variables whose content is stored in files in your ~/.config and to which fish serializes access via some IPC mechanism.

#! /bin/fish -
set -U number (math 0$number+1)
echo Hello Mr. This is your {$number}th log in
| improve this answer | |

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.