Run a Bash Script automatically upon login - bash

I wrote a script that sends the date and username of the person who logs in to a log file to keep a record of who has logged in. I am wondering how can you set this script to execute automatically when a user logs in rather than have to manually run it in the terminal. NOTE: the USERNAME is the current user that is logged in.
my code:
#!/bin/bash
printf "$(date) $HOSTNAME booted!\n" >> /home/USERNAME/boot.log

A more elegant way to solve this problem is to read from log files that are already being written and cannot be changed by the user. No one could say it better than Bjørne Malmanger's in his answer:
I wouldn't trust the user to GIVE you the information. As root you
TAKE it ;-)
A nice way to do this is the last command, which is great because it neatly displays all logins: Graphical, console and SSH.
last
A less elegant but still secure way is to do a grep on /var/log/auth.log. On my Gnome/Ubuntu system I can use this to track graphical logins:
grep "session opened for user USERNAME"
The right pattern for your machine needs to be found for each login type: graphical, console and SSH. This is cumbersome, but you might need to do it if you need information that goes further back than last reaches.
To directly answer your question:
You can modify the script like this to get the username
#!bin/bash
printf "$(date) $HOSTNAME booted!\n" >> /home/$(whoami)/boot.log
And add this line to /etc/profile
. /path/to/script.sh
This is not secure though because the user will be able to edit his own log

Why don't you use the last command?
I wouldn't trust the user to GIVE you the information. As root you TAKE it ;-)

Put it in ~/.bash_profile. It will be run each time they log in.
More information is available at the women's rights page (i.e. man bash).

Related

using grep in a script which prompt user for input

I have written one shell script which ask for some username and password from standart input.
Once username and password is typed there is a output depending upon the parameters passed in the script.
Say my script name is XYZ.ksh.
Now my problem is that users of these script want to use want to use this script in conjugation with other shell commands like grep, less, more, wc etc.
Normally yes they can use
XYZ.ksh | grep abc
But in my case since XYZ is prompting for username and password we are not able to use "|" in front of that. It blocks forever.
I just wanted to know how can I implement the functinality.
What I tried
I tried taking input of "more commands " from user where user types things like "| grep abc"
but when i used this input in my script it did not work.
Use <<< like this:
XYZ.ksh <<< "your inputs" | grep abc
In your script you can test to see if stdout is connected to a terminal with:
if [[ -t 1 ]]
That way you can supress the prompt if the output is not going to the console.
Alternatively, with your "more commands" solution, run the command connected to a named pipe.
There are multiple solutions commonly used for this kind of problem but none of them is perfect :
Read password from standard input. It makes it really hard to use the script in pipes. This method is used by commands that deal with changing passwords : passwd, smbpasswd
Provide username and password in the command line parameters. This solution is good for using the script in pipes, but command line can be viewed by anyone, using ps -ef for exemple. This is used by mysql, htpasswd, sqlplus, ...
Store username and password unencrypted in a file in user's home directory. This solution is good for using the script in pipes, but the script must check if the file is visible or modifiable by other users. This is used by mysql
Store private key in local file and public key in distant file, as used by SSH. You must have a good encryption knowledge to do this correctly (or rely on SSH), but it's excellent for use in pipes, even creating pipes accross different machines !
Don't deal with passwords, and assume that if a user is logged in in the system, he has the right to run the program. You may give execute privilege only to one group to filter who can use the program. This is used by sqlplus from Oracle, VirtualBox, games on some Linux distributions, ...
My preferred solution would be the last, as the system is certainly better than any program I could write with regard to security.
If the password is used to login to some other service, then I would probably go for the private file containing the password.
One less-than-optimal possibility is to display the prompt to stderr instead of stdout.
echo -n "Username:" >/dev/stderr
A better solution would be to check stdin of the shell. If it's a terminal, then open it for writing and redirect to that file. Unfortunately, I'm not sure how to do that in bash or ksh; perhaps something like
echo -n "Username:" >/dev/tty
You can use (I assume you are reading username and password in your script with read)
(
read -p "user:" USER
read -p "pass:" PASS
) < /dev/tty > /dev/tty
and you'll be able to run
$ cmd | XYZ.ksh
However, I agree with other answers: just don't ask for user and password and give the correct permissions to the script to allow access.

Error logging in via FTP script in KornShell

I am trying to FTP a file using a script in KornShell (ksh) and I am getting a login failed message. I can login manually just fine but when I try the automated script, it does not like the password portion of the login information.
Here's my script:
ftp -n ftp.stmp.com <<EOF
user quser pass Sky3s3ch
binary
hash
prompt
put chr*.dat
EOF
And this is the error that I get:
dns: /u04/lms/ora_shell/clients/STMP > LMS_STMP_ECHI_FTP.ksh
Not logged in.
Login failed.
Please login with USER and PASS.
Hash mark printing on (1024 bytes/hash mark).
Interactive mode off.
Please login with USER and PASS.
Please login with USER and PASS.
I would appreciate any help I can get in figuring this out. Thanks in advance.
there are many different ftp clients, but I'm not familiar with one that requires the word pass as part of a single line login like you are using. Try
ftp -n ftp.stmp.com <<EOF
user quser Sky3s3ch
. . .
EOF
Another common form is to move the hostname inside the ftp input stream, i.e.
ftp -in <<EOF
open ftp.stmp.com
quser Sky3s3ch
. . .
EOF
I don't have my sample code availab.e You may need user on the 2nd line of input, but I don't think so.
Edit
Finally, I noticed you have put chr*.dat in your input script. To transfer multiple files at the same time, you'll need the mput command instead.
I hope this helps.

FTP inside a shell script not working

My host upgraded my version of FreeBSD and now one of my scripts is broken. The script simply uploads a data feed to google for their merchant service.
The script (that was working prior to the upgrade):
ftp ftp://myusername:mypassword#uploads.google.com/<<END_SCRIPT
ascii
put /usr/www/users/myname/feeds/mymerchantfile.txt mymerchantfile.txt
exit
END_SCRIPT
Now the script says "unknown host". The same script works on OSX.
I've tried removing the "ftp://". - No effect
I can log in from the command line if I enter the username and password manually.
I've search around for other solutions and have also tried the following:
HOST='uploads.google.com'
USER='myusername'
PASSWD='mypassword'
ftp -dni <<END_SCRIPT
open $HOST
quote USER $USER
quote PASS $PASS
ascii
put /usr/www/users/myname/feeds/mymerchantfile.txt mymerchantfile.txt
END_SCRIPT
And
HOST='uploads.google.com'
USER='myusername'
PASSWD='mypassword'
ftp -dni <<END_SCRIPT
open $HOST
user $USER $PASS
ascii
put /usr/www/users/myname/feeds/mymerchantfile.txt mymerchantfile.txt
END_SCRIPT
Nothing I can find online seems to be doing the trick. Does anyone have any other ideas? I don't want to use a .netrc file since it is executed by cron under a different user.
ftp(1) shows that there is a simple -u command line switch to upload a file; and since ascii is the default (shudder), maybe you can replace your whole script with one command line:
ftp -u ftp://username:password#uploads.google.com/mymerchantfile.txt\
/usr/www/users/myname/feeds/mymerchantfile.txt
(Long line wrapped with \\n, feel free to remove the backslash and place it all on one line.)
ftp $HOSTNAME <<EOFEOF
$USER
$PASS
ascii
put $LOCALFILE $REMOTETEMPFILE
rename $REMOTETEMPFILE $REMOTEFINALFILE
EOFEOF
Please note that the above code can be easily broken by, for example, using spaces in the variables in question. Also, this method gives you virtually no way to detect and handle failure reliably.
Look into the expect tool if you haven't already. You may find that it solves problems you didn't know you had.
Some ideas:
just a thought since this is executed in a subshell which should inherit correctly from parent, does an env show any difference when executed from within the script than from the shell?
Do you use a correct "shebang"?
Any proxy that requires authentication?
Can you ping the host?
In BSD, you can create a NETRC script that ftp can use for logging on. You can even specify the NETRC file in your ftp command too using the -N parameter. Otherwise, the default NETRC is used (which is $HOME/.netrc).
Can you check if there's a difference in the environment between your shell-login, and the cron-job? From your login, run env, and look out for ftp_proxy and http_proxy.
Next, include a line in the cron-job that will dump the environment, e.g. env >/tmp/your.env.
Maybe there's some difference...Also, did you double-check your correct usage of the -n switch?

Crontab Script File Syntax

I am in a UNIX system administration course at school and have to generate a Cron job that does the following:
Queries the system each hour to find
out who is logged in.
Mails the result to my email account.
I know that the actual crontab will look like the following:
# Check to see who is logged in every hour.
MAILTO="me#email.com"
0 * * * * root /tmp/loggedin.sh
OR
# Check to see who is logged in every hour.
MAILTO="me#email.com"
#hourly /tmp/loggedin.sh
But I have been Googling for some time and have been unable to find any examples of what exactly the .sh file should look like. I know it starts with:
#!/bin/bash
# Shell script to see who is logged in, to be run every hour.
And I have no idea what else to put in there. Any help is greatly appreciated!
I think who should do the trick. It will show you a list of all the users that are logged in to the system at a time. You can write this to a file and then have it mailed to you.
w would get you what the people logged in are currently doing.
So, the script would look like:
#!/bin/sh
HOME=<your home directory>
who > ${HOME}/usersLoggedIn.txt
w > ${HOME}/whatLoggedInUsersAreDoing.txt
${HOME} refers to your home directory. On the command prompt, echo $HOME should give you your home directory. The output of the command who and w will get redirected to the files usersLoggedIn.txt and whattLoggedInUsersAreDoing.txt within your home directory. You can, of course, change the directory and file names to which you want this data to be written.
HTH,
Sriram
Any output from a cron job is mailed to the user. If you don't care about the subject line your cron entry is as simple as this:
#hourly w
If you do care about it,use mail(1):
#hourly w|mail -s'Users logged in' me#work.example.com
#!/bin/bash
# Shell script to see who is logged in, to be run every hour.
who | mail -s "Who is logged in `date`" "$MAILTO"

How do I get the name of the active user via the command line in OS X?

How do I get the name of the active user via the command line in OS X?
as 'whoami' has been obsoleted, it's probably more forward compatible to use:
id -un
If you'd like to display the full name (instead of the username), add the -F flag:
$ id -F
Andrew Havens
I'm pretty sure the terminal in OS X is just like unix, so the command would be:
whoami
I don't have a mac on me at the moment so someone correct me if I'm wrong.
NOTE - The whoami utility has been obsoleted, and is equivalent to id -un. It will give you the current user
whoami
EDIT
The whoami utility has been obsoleted by the id(1) utility, and is equivalent to id -un. The command id -p is suggested for normal interactive use.
Via here
Checking the owner of /dev/console seems to work well.
stat -f "%Su" /dev/console
There are two ways-
whoami
or
echo $USER
You can also use the logname command from the BSD General Commands Manual under Linux or MacOS to see the username of the user currently logged in, even if the user is performing a sudo operation. This is useful, for instance, when modifying a user's crontab while installing a system-wide package with sudo: crontab -u $(logname)
Per man logname:
LOGNAME(1)
NAME
logname -- display user's login name
If you want to know who's currently logged in to the system:
$ w
15:56:14 up 5 days, 20:58, 6 users, load average: 0.43, 0.53, 0.50
USER TTY LOGIN# IDLE JCPU PCPU WHAT
me pts/2 Fri19 1:03m 0.98s 0.98s -/bin/bash
me pts/3 09:55 6:00m 0.43s 0.43s /bin/bash
me pts/5 15:56 0.00s 0.23s 0.00s w
(This is from a Linux system; the formatting on OS X may be slightly different, but the information should be about the same.)
There may be multiple login sessions; UNIX is designed to be a multi-user system, after all.
The question has not been completely answered, IMHO. I will try to explain: I have a crontab entry that schedules a bash shell command procedure, that in turn does some cleanup of my files; and, when done, sends a notification to me using the OS X notification center (with the command osascript -e 'display notification ...). If someone (e.g. my wife or my daughter) switches the current user of the computer to her, leaving me in the background, the cron script fails when sending the notification.
So, Who is the current user means Has some other people become the effective user leaving me in the background? Do stat -f "%Su" /dev/console returns the current active user name?
The answer is yes; so, now my crontab shell script has been modified in the following way:
...
if [ "$(/usr/bin/stat -f ""%Su"" /dev/console)" = "loreti" ]
then /usr/bin/osascript -e \
'display notification "Cleanup done" sound name "sosumi" with title "myCleanup"'
fi
getting username in MAC terminal is easy...
I generally use whoami in terminal...
For example, in this case, I needed that to install Tomcat Server...
You can also retrieve it from the environment variables, but that is probably not secure, so I would go with Andrew's answer.
printenv USER
If you need to retrieve it from an app, like Node, it's easier to get it from the environment variables, such as
process.env.USER.
Define 'active user'.
If the question is 'who is the logged in user', then 'who am i' or 'whoami' is fine (though they give different answers - 'whoami' reports just a user name; 'who am i' reports on terminal and login time too).
If the question is 'which user ID is the effective ID for the shell', then it is often better to use 'id'. This reports on the real and effective user ID and group ID, and on the supplementary group IDs too. This might matter if the shell is running SUID or SGID.
you can open terminal and write down following command:
id -un
or
whoami
This will return your current login username.

Resources