What is the *nix command to view a user's default login shell - linux

What is the *nix command to view a user's default login shell?
I can change the default login shell with chsh, but I don't know how to get what is the user's default shell.
Pseudocode
$ get-shell
/usr/bin/zsh

The canonical way to query the /etc/passwd file for this information is with getent. You can parse getent output with standard tools such as cut to extract the user's login shell. For example:
$ getent passwd $LOGNAME | cut -d: -f7
/bin/bash

The command is finger.
[ken#hero ~]$ finger ken
Login: ken Name: Kenneth Berland
Directory: /home/ken Shell: /bin/tcsh
On since Fri Jun 15 16:11 (PDT) on pts/0 from 70.35.47.130
1 hour 59 minutes idle
On since Fri Jun 15 18:17 (PDT) on pts/2 from 70.35.47.130
New mail received Fri Jun 15 18:16 2012 (PDT)
Unread since Fri Jun 15 17:05 2012 (PDT)
No Plan.

The login shell is defined in /etc/passwd. So you can do:
grep username /etc/passwd

I think what you are looking for is this:
#!/bin/bash
grep "^$1" /etc/passwd | cut -d ':' -f 7
Save that as get-shell somewhere in your path (probably ~/bin) and then call it like:
get-shell userfoo

SHELL variable is used to represent user's current shell
echo $SHELL

Related

How to have bash script's log file be auto-created after removal

I have a bash script file date.sh:
#!/bin/bash
while true
do
sleep 1
echo "date------ "$(date)
done
I run it
$ ./date.sh >> date.log 2>&1 &
I can see a date.log in there and be updating, but after I removed it, it won't be auto created, even I manually recreated it, the file won't update , I want date.log be auto created and update after it be removed.
In this code, date.log is opened just once:
./date.sh >> date.log 2>&1 &
If you want date.log to recreate itself if missing, you need to re-open each time that you write to it:
#!/bin/sh
while true; do
sleep 1
echo "date------ $(date)" >>date.log
done
Because the redirection >>date.log is inside the loop, the file is opened (and closed) with each loop. That is what is needed to re-create the file.
You can then run it:
./date.sh &
Now, if you delete or rename date.log, a new file called date.log will be created and written to.
Note that re-opening and re-closing the file with each loop is less efficient. Unless you want the re-create-itself feature, it is faster to open and close just once.
Example
This shows that we can delete date.log while the script is running in the background and the file will soon be recreated and appended to:
$ ./date.sh &
[1] 15678
$ cat date.log
date------ Sat Jul 30 00:51:28 PDT 2016
date------ Sat Jul 30 00:51:29 PDT 2016
date------ Sat Jul 30 00:51:30 PDT 2016
date------ Sat Jul 30 00:51:31 PDT 2016
$ rm -f date.log
$ cat date.log
date------ Sat Jul 30 00:51:38 PDT 2016
date------ Sat Jul 30 00:51:39 PDT 2016
date------ Sat Jul 30 00:51:40 PDT 2016
date------ Sat Jul 30 00:51:41 PDT 2016
What if date.sh cannot be modified
Suppose that date.sh is owned by others and we cannot modify it. In that case:
./date.sh | awk -v f=date.log '{print>>f; close(f)}' &
awk loops through each line of input and, for each line, it opens date.log, appends to it, and closes it.
Alternatively, if for some reason we wanted to stick with pure shell:
./date.sh | while IFS= read -r line; do printf "%s\n" "$line" >>date.log; done &

Running Linux Functions inside Sqlplus

Can I call user-created shell functions from inside Oracle SQLPLUS using the HOST command? If not, what's the best way to approach the problem?
Essentially, I want to run a shell file:
Shell commands
sqlplus
#file.sql
HOST mylinuxfunction...
#file2.sql
HOST anotherlinuxfunction..
exit
Shell commands
Thank you!
You can surely invoke HOST commands from SQLPlus scripts, but I imagine you are really asking whether you can use the return values from your linux functions in the rest of your SQLPlus scripts. And you also might be wanting to use results from the SQL queries in your linux functions.
If you do not need to pass SQL information to your linux functions, and do not need to access the results from the linux functions in the remainder of your SQL, then what you have will almost work. This would
date
sqlplus / << xxENDxx \
#file.sql
HOST mylinuxfunction...
#file2.sql
HOST anotherlinuxfunction..
exit
xxENDxx
date
Now if you want to get information from your linux function into SQL, you will have to use external tables; a lot of setup, but look here: https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:439619916584 and search for "but here is another interesting approach, available in 10.2.0.5 and up:"
If you want to pass information from Linux commands that are done before invoking SQLPlus into your SQL commands, that would be something like this, that inserts a row into the uptimes table with output from the uptime command that is stored in the BASH variable $UPTIMES:
#!/bin/bash
if [ "$1" = "" ]
then
echo Missing User ID parm
exit 1
else
USER_ID=$1
fi
read -p "Enter Your password for Oracle instance $ORACLE_SID for user $USER_ID: " PW
UPTIMES=`uptime | awk -F, '{print $3, $4, $5}' | awk '{printf "%2.2f,%2.2f,%2.2f\n", $3, $4, $5}'`
sqlplus /nolog << xxENDxx \
connect $USER_ID/$PW
insert into uptimes (date_stamp, one_min, five_min, fifteen_min) values (sysdate, $UPTIMES);
HOST ls -o uptimes.sh
--#file2.sql
select * from uptimes;
HOST du -sh .
exit
xxENDxx
date
Invoking the above gives this:
oracle. (/home/oracle/sql)
Linux> ./uptimes.sh mark.stewart
Enter Your password for Oracle instance ecs03 for user mark.stewart: xxxx
SQL*Plus: Release 12.1.0.2.0 Production on Thu Mar 17 20:09:36 2016
Dev:#> Connected.
Dev:MARK.STEWART#ecs03> Dev:MARK.STEWART#ecs03>
1 row created.
Dev:MARK.STEWART#ecs03> -rwxr-xr-x. 1 oracle 548 Mar 17 20:09 uptimes.sh
Dev:MARK.STEWART#ecs03> Dev:MARK.STEWART#ecs03>
DATE_STAM ONE_MIN FIVE_MIN FIFTEEN_MIN
--------- ---------- ---------- -----------
17-MAR-16 0 .01 .05
17-MAR-16 0 .01 .05
17-MAR-16 0 .01 .05
Dev:MARK.STEWART#ecs03> 146M .
Dev:MARK.STEWART#ecs03> Disconnected from Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
Thu Mar 17 20:09:36 CET 2016
oracle. (/home/oracle/sql)
Linux>

Salt cmd.run to NOT show the server name

When running a command from a salt-master linux box I always get something similar to the following result:
[root#salt-master ~]# salt 'target-server' cmd.run 'date'
target-server:
Fri Jul 24 22:41:44 UTC 2015
What can I do to get only the result of the command and NOT the targeted server too?
[root#salt-master ~]# salt 'target-server' cmd.run 'date' --SOMETHING I HAVE TO DO---
Fri Jul 24 22:41:44 UTC 2015
You can use Salt's JSON output format together with the command line utility jq to extract the values you need. On CentOS you'll need to install the package jq to use it.
The command line
salt 'target-server' cmd.run 'date' --out json | jq -r '.[]'
will output
Sun Jul 26 15:17:40 UTC 2015
(the -r option prevents double quotes around the output).
There are several other output formats available for Salt.

How to print the previous linux command's output?

The problem is:
After user enter a linux command.
How can I get the output of the first command using another command?
Note: we cannot redirect output of first command to somewhere.
Using history expansion
$ date -d "12:00"
Thu Sep 19 12:00:00 EDT 2013
$ d=$(!!)
$ echo $d
Thu Sep 19 12:00:00 EDT 2013

Perform action when user logs in via SSH from a particular host

I have a quesiton that puzzles me and I wonder if anyone has attempted to achieve the following:
Let's assume that this is the result of my 'last' command in a Linux environment:
root pts/1 192.168.1.10 Wed Feb 10 07:04 - 07:57 (00:52)
root pts/2 Tue Feb 9 22:00 - 00:13 (02:13)
How can I setup a particular action (say for example a modified MOTD or sending an email) if the the 'root' user has logged in from 192.168.1.10. Is there a way of capturing this information?
The second part of this question is that how can I make the above check a bit more robust - i.e. if I have the following:
mary pts/1 192.168.1.10 Wed Feb 10 07:04 - 07:57 (00:52)
bob pts/2 Tue Feb 9 22:00 - 00:13 (02:13)
Now I'd like to perform an action if the username is equal to 'mary' and the host is 192.168.1.10.
Any suggestions are welcomed.
Thank you in advance.
There's a special file /etc/ssh/sshrc where you can put some commands that will runs each time someone connect by ssh. I wrote that for you :
#!/bin/bash
mail=user#domain.tld
monitored_user=root
monitored_ip=x.x.x.x
hostname=$(hostname)
# add a welcome message:
printf >&2 "\nWelcome on $hostname $USER\n"
read -d " " ip <<< $SSH_CONNECTION
[[ $ip == $monitored_ip && $USER == $monitored_user ]] || exit 0
date=$(date "+%d.%m.%Y %Hh%M")
reverse=$(dig -x $ip +short)
mail -s "Connexion of $USER on $hostname" $mail <<EOF
IP: $ip
Reverse: $reverse
Date: $date
EOF
Put this script in a file, then put the full path of the script in /etc/ssh/sshrc
In man ssh :
/etc/ssh/sshrc :
Commands in this file are executed by ssh when the user
logs in, just before the user's shell (or command) is started. See the
sshd(8) manual page for more information.
Thanks for all your replies. Eventually I managed to find a solution which does work for the time being but it does have one flaw which I'll point out in a minute.
I have added the following to my /etc/bashrc file (or /etc/bash.bashrc whatever environment you're using):
HOST="192.168.0.1"
RHOST=`who am i | sed -n 's/.*(\([^) ]*\).*/\1/p; 1q'`
if [ "$RHOST" == "$HOST" ]; then
echo "SAY WHAT!"
#add further actions here if needed
fi
The flaw that I was talking about before may actually not be a flaw. If you're already SSH-ed into the system, and you want to SSH to a host which lives on the same IP, say ssh root#your-host who am i would then print 'your-host' but I think that's the way it should be.
Needless to say that the above sed statement can be modified so you can capture the username as well, and you can extend the if/else statement to suite your needs.
Thank you again for all your replies.
You can add something to /etc/profile or equivalent that does something depending on the value of $SSH_CLIENT.
It looks like you are using last because it reads /var/log/wtmp by default which is a record of logins. The who command also allows you to read the same file but with an interface more to your needs.
For example:
$ who --ips /var/log/wtmp | grep '^msw.*127.0.0.1'
msw pts/2 2012-10-07 15:52 127.0.0.1
msw pts/3 2012-10-07 15:55 127.0.0.1
where neither of those sessions were active, but rather historic and logged.
In ubuntu i put a script in
/etc/profile.d
and when someone(user ssh) log in, it send an email to my mail
#/etc/profile.d/run_on_loggin.sh
echo $(who i am) | mail -s 'SSH Login Notification' mymail#hotmail.com
I want to create a php file with smtp, to send email with my mail to me...
some times hotmail saved in spam...
if i have the php file i will run like this...
if i want to pass var to file php run like this...
excuse my english :3
note: i think this command run from user, be carefully if the user doen't has permission to use some command or send email.
One way would be to run a simple script periodically:
#!/bin/bash
users=$(last | sed -ne '/192\.168\.1\.10/ s/\([^ ]*\).*/\1/p')
for user in $users; do
sendmail "$user" < email.txt
done
This would pipe the last command into sed to extract a user list and save it into the variable $users. The sed command uses the -n flag so it only prints what we tell it to. First, we select lines that contain the specified IP, with the /192\.168\.1\.10/ "address". On those lines, we attempt to extract the characters before a space, and if we succeed we print the result.
Then, we can loop through the $users variable and act accordingly.
One way to call this repeatedly would be through cron, and a simpler way would be to do while true; do ./my_script.bash; sleep 60; done.

Resources