run multiple commands while login to linux host - linux

I log in to multiple Linux hosts on everyday basis using my LDAP username and then sudo su to ROOT and ORACLE user and check the database status.
As I do this everyday basis on many Linux hosts, I am curious to see whether I can run all commands in single command line?
I tried following, but it didn't help
how to execute multiple commands after sudo command
Example:
After I login using my LDAP user to Linux Host, I want to run following commands in one single command
sudo su - root -c "su - oracle; ps -ef |grep pmon; crsctl stat res -t "
After login to root, then need to switch to oracle user and then run commands

The reason your command as written doesn't work is because you don't actually run your monitoring commands as the oracle user.
The command you give to the first su invocation, su - oracle; ps -ef | grep pmon; crsctl stat res -t, attempts to do three things in sequence as root: firstly, it calls su to spawn an interactive shell as oracle; after this shell exits, it runs the ps pipeline; finally, it runs the crsctl command. Since the monitoring commands run after the second su has finished, they run as root, which isn't what you want.
The smallest change to your command that will make it work is the following:
sudo su - root -c "su - oracle -c \"ps -ef | grep pmon; crsctl stat res -t\""
(Note that you need to escape the inner pair of quotes with backslashes so that they don't end the outer quoted string.) However, you can simplify this command significantly: the first optimization you can make is to get rid of the first su call. You don't need it, because you're already root from sudo:
sudo su - oracle -c "ps -ef | grep pmon; crsctl stat res -t"
You can still make it better, though. If sudo is configured to allow you to switch to any user (not just root), you don't need to use su at all. Instead, just specify the user you want using sudo -u:
sudo -u oracle sh -c "ps -ef | grep pmon; crsctl stat res -t"
(Note that you need to add an explicit call to sh so that you can run the entire set of commands as oracle and not just the first one. sudo's documentation claims that you can use its -i or -s options for this, but they didn't work as documented in my tests.)
If you want to keep an interactive shell as the oracle user after this command, you can simply make the last command sudo runs be an interactive shell. In this case, you probably also want to pass -i to sudo so that the interactive shell has the login environment of oracle:
sudo -i -u oracle sh -c "ps -ef | grep pmon; crsctl stat res -t; $SHELL"

Related

Difference between sudo -s and sudo su in mac os

Both sudo -s and sudo su makes user root. is there any some difference?
With sudo -s
with sudo su
From man sudo:
-s, --shell
Run the shell specified by the SHELL environment variable if it is set or the shell specified by the invoking user's password
database entry. If a command is specified, it is passed to the shell for execution via the shell's -c option. If no command is
specified, an interactive shell is executed.
So -s keeps your current shell (bash in this case), while omitting it uses the shell of the root user (sh). Myself, I prefer sudo -Es to keep both my shell and environment variables.

change user and run ssh instruction in 1 line

I'm trying to change my user to one that doesn't need password to run ssh instructions and then do exactly that, run an ssh instruction. What I have now is:
sudo su - testUser ssh testUser#server2 'cat /home/randomUser/hola.txt'
But I'm getting the answer:
/usr/bin/ssh: /usr/bin/ssh: cannot execute binary file
if I put the instructions in a different file called testit like this:
ssh testUser#server2
cat /home/randomUser/hola.txt
and I run:
sudo su - testUser < testit
it works!, but I need to use the one line instruction, someone know what should I change to make it work?
sudo su - testUser
why don't you use just sudo -u testUser as it is supposed to be used?
But anyway, manual pages for the tools you are using is a good start. For sudo:
sudo [...] [command]
This looks good and fits into your example.
For su:
su [options] [username]
Ola ... su does not have any argument command, unless you provide also -c switch, which is written also in the manual page. And it is [option], so it should come in front of [username]! Something like this should do the job:
sudo su -l -c "ssh testUser#server2 'cat /home/randomUser/hola.txt'" testUser
but as I already mentioned, it can be significantly simplified by using sudo only:
sudo -i -u testUser "ssh testUser#server2 'cat /home/randomUser/hola.txt'"

How to run a script as a different user without authentication? [duplicate]

I have script.sh that must be run as user2. However, this script can only be run under user1 in my application.
I would like the following command to run:
su user2 -C script.sh
but be able to run without password.
I also want this to be very restrictive, as in user1 can only run script.sh under user2 and nothing else.
I've tried doing this with sudoers file and just got endlessly confused after hours of trying.
If somebody can provide an explicit example of how this can be accomplished (instead of something generic like use sudoers), it would be greatly appreciated.
try running:
su -c "Your command right here" -s /bin/sh username
This will run the command as username given that you have permissions to sudo as that user.
Call visudo and add this:
user1 ALL=(user2) NOPASSWD: /home/user2/bin/test.sh
The command paths must be absolute! Then call sudo -u user2 /home/user2/bin/test.sh from a user1 shell. Done.
`su -c "Your command right here" -s /bin/sh username`
The above command is correct, but on Red Hat if selinux is enforcing it will not allow cron to execute scripts as another user. example;
execl: couldn't exec /bin/sh
execl: Permission denied
I had to install setroubleshoot and setools and run the following to allow it:
yum install setroubleshoot setools
sealert -a /var/log/audit/audit.log
grep crond /var/log/audit/audit.log | audit2allow -M mypol
semodule -i mypol.p

Use source with script that contains sudo command

I have a script that copies files between servers. I am using the lsof command to make sure that the file is not being written to before being moved. The user running the script and the user writing to the file are different, so I need to sudo to the file owner. Here is the relevant line in the sudoers file :
userA ALL=(userB:userB) NOPASSWD: ALL
In the main script (ran as userA), I have tried calling sudo then the subscript containing the lsof command:
sudo su - userB -c 'source ./getOpenFiles.sh'
getOpenFiles.sh has this one line:
#!/bin/bash
lsofResult=$(/usr/sbin/lsof "${sourcePath}")
I have also tried calling the subscript:
source ./getOpenFiles.sh
Then have the first line of the subscript be the sudo:
#!/bin/bash
sudo su - banjobs
lsofResult=$(/usr/sbin/lsof "${sourcePath}")`.
Neither solution is working.
What you actually want is something more like:
lsofResult=$(sudo -u banjobs lsof "${sourcePath}")
Let's go over why the other approaches didn't work one-at-a-time:
Running source under sudo su -c
sudo su - userB -c 'source ./getOpenFiles.sh'
...uses sudo to run su, which runs sh -c 'source ./getOpenFiles.sh'. This doesn't work for several independent reasons:
sh -c 'source ./getOpenFiles.sh' relies on the source keyword being available in /bin/sh, but this is a bash extension.
Even if your /bin/sh is provided by bash, this still defeats the purpose of using source: By starting a new copy of /bin/sh and sourcing your script into that, you're defining the variable in the new shell, not in the original shell that started sudo su.
Running sudo su - banjobs, followed by lsofResult=$(/usr/sbin/lsof "${sourcePath}")
...means that lsofResult=$(...) doesn't run until after sudo su - banjobs exits. If sudo su - banjobs has exited, then the current user isn't banjobs any more, so the sudo command has no effect whatsoever on the lsof.
Demonstrating, in detail, how to test this (for folks who don't have a banoff or userB account on their system):
# place relevant contents in sourceme.bash
# switching from lsof to fuser for this test since OS X lsof does not accept a directory
# as an argument.
cat >sourceme.bash <<'EOF'
lsofResult=$(sudo -u root fuser "${sourcePath}" 2>&1)
EOF
# set sourcePath in the outer shell
sourcePath=$PWD
source sourceme.bash
declare -p lsofResult
...yields, on my system, output akin to the following:
declare -- lsofResult="/Users/chaduffy/tmp: 17165c 17686c 17687c 17688c 17689c 17690c"
...showing that the code in question did in fact work as described.

su command in shell script

I have a script which copies a file, then untar and install it (agent-service) on multiple systems (IPs are read from systems.txt file). In the script, I wanted to start the agent-service as user "test". However after the script execution, when I check the target system, the agent-service is shown as running as "root" user. What could be wrong here? Am I not using su command correct within the script?
~]# ps -ef | grep agent-service
root 23511 15196 0 02:12 pts/3 00:00:00 agent-service
Script>
#!/bin/bash
export AGENT=linux-5.8.1.tar.gz
while read host; do
scp $AGENT root#$host:/opt
ssh -n root#$host 'cd /opt/linux;
tar zxvf linux-5.8.1.tar.gz;
mkdir /opt/hyperic;
useradd -m test;
chown -R test:test /opt/linux;
su - test;
/opt/linux/agent-service start'
done < systems.txt
Using su as you do here spawns a new shell that has nothing to do thus exits immediately.
Either pass the command to su:
su - test -c /opt/linux/agent-service start
Or use sudo in a similar manner:
sudo -u test /opt/linux/agent-service start

Resources