How to run Cron Job to creates files as User file instead of root file - linux

Why the output file from this is owned by root and not w3svcsadm?
sudo -u w3svcsadm echo "TEST ran" > /home/your/emaildigest/TEST_$( date +%Y%m%d%H%M%S ).output
I'm running into some issues with cron, and I believe this is the key to my problems.

Using the -u flag with sudo executes the command 'echo "TEST ran"' as the user w3svcasadm, but that command isn't the thing doing the work of outputting to a file, which is done by the '>' operator. By the time bash is using that operator, it's already switched back to the user running the shell. If that user is root, then the file will be created under root. In your script, you could use "su w3svcsadm" to switch the shell user before executing that command, then you wouldn't have to use that -u flag at all.

Related

Unix function can not called after switch user in shell script

The below script executing with root user.After switch user Unix function showing error.
test.sh
#!/bin/bash
fn_test()
{
echo "This is function"
}
whoami
fn_test
su - oracle<<EOF
whoami
fn_test #This function not called
EOF
exit 0
O/P
root $ ./test.sh
root
This is function
oracle
-ksh[2]: fn_test: not found [No such file or directory]
You have a confusion on what su actually does: you hope it to just swith user when it does start a new process. You can control it with ps in an interactive session: you see the original shell, the su command, the new shell launched by su and the current ps command.
As a shell function is local to the shell it cannot be used in a (grand) child shell.
The best that you can hope is to pass something through the environment. I know that aliases can be put there unsure for functions. Moreover, this is absolutely shell dependant and might not be portable.

Switch to root user within bash script

Im currently logged in as admin and I want to edit the /etc/hosts file which required root access.
I'm not able to make the changes. The script gets executed sucessfully but the changes arent made.
My Script - Runs Sucessfully when executed from terminal
sudo -s
echo "127.0.0.1" >> /etc/hosts
su admin
sudo -s - switches to root without password when executed from terminal
su admin - switches back to admin user when run on terminal
My /etc/hosts file remains empty after running the script
There is no need to actually switch your user within the script.
Also, you can't echo something as root like that because the redirect (>>) is executed by the shell.
A possible workaround is using tee:
echo "127.0.0.1" | sudo tee -a /etc/hosts
Further explanation:
tee basically takes the data from the standard input and writes it either to the standard output, or to a file. For more information see the commands manual ($ man tee)

Linux: how to change maximum number of files a process can open?

I have to execute a process on a cluster of machines. Size of cluster is of order 100. So I cannot execute processes manually, I have to execute them by script(which uses ssh, currently I am using python-paramiko for this). Number of tcp sockets these processes open is more than 1024(default limit of linux.) So I need to change that using {ulimit -n 10000}. This makes the changes for that shell session only. And this command works only with root user. So my script is not able to do that.
I tried to execute this command
sudo su && ulimit -n 10000 && <commandToExecuteMyProcess>
But this didn't work. The commands after "sudo su" didn't execute at all. They execute only when I logout of the su session.
This article shows way to make the changes permanently. But when I open limits.conf, I didn't find anything there. It only has some commented notes.
Please suggest me some way to increase the limit permanently or change it by script for each session.
That's not how it works: sudo su just opens a new shell so you can introduce commands as root, and after you exit that shell it executes the rest of the line as normal user.
Second: your this is a special case because ulimit is not actually a program, but a bash shell built-in command, so it must be used within bash, that is why something like sudo ulimit -n 10000 won't work: sudo can't find that program because it doesn't exist.
So, the only alternative is a bit ugly but works:
sudo bash -c 'ulimit -n 10000 && <command>'
Everything inside '...' will execute in a bash session of the root user.
Note that you can replace && with ; in this case: that's because it is being executed as root and ulimit -n 10000 will always complete successfully.

how to write a bash shell script to ssh to remote machine and change user and export a env variable and do other commands

I have a webservice that runs on multiple different remote redhat machines. Whenever I want to update the service I will sync down the new webservice source code written in perl from a version control depot(I use perforce) and restart the service using that new synced down perl code. I think it is too boring to log to remote machines one by one and do that series of commands to restart the service one by one manully. So I wrote a bash script update.sh like below in order to "do it one time one place, update all machines". I will run this shell script in my local machine. But it seems that it won't work. It only execute the first command "sudo -u webservice_username -i" as I can tell from the command line in my local machine. (The code below only shows how it will update one of the remote webservice. The "export P4USER=myname" is for usage of perforce client)
#!/bin/sh
ssh myname#remotehost1 'sudo -u webservice_username -i ; export P4USER=myname; cd dir ; p4 sync ; cd bin ; ./prog --domain=config_file restart ; tail -f ../logs/service.log'
Why I know the only first command is executed? Well because after I input the password for the ssh on my local machine, it shows:
Your environment has been modified. Please check /tmp/webservice.env.
And it just gets stuck there. I mean no return.
As suggested by a commentor, I added "-t" for ssh
#!/bin/sh
ssh -t myname#remotehost1 'sudo -u webservice_username -i ; export P4USER=myname; cd dir ; p4 sync ; cd bin ; ./prog --domain=config_file restart ; tail -f ../logs/service.log'
This would let the local commandline return. But it seems weird, it cannot cd to that "dir", it says "cd:dir: No such file or directory" it also says "p4: command not found". So it looks like the sudo -u command executes with no effect and the export command has either not executed or excuted with no effect.
A detailed local log file is like below:
Your environment has been modified. Please check /tmp/dir/.env.
bash: line 0: cd: dir: No such file or directory
bash: p4: command not found
bash: line 0: cd: bin: No such file or directory
bash: ./prog: No such file or directory
tail: cannot open `../logs/service.log' for reading: No such file or directory
tail: no files remaining
Instead of connecting via ssh and then immediately changing users, can you not use something like ssh -t webservice_username#remotehost1 to connect with the desired username to begin with? That would avoid needing to sudo altogether.
If that isn't a possibility, try wrapping up all of the commands that you want to run in a shell script and store it on the remote machine. If you can get your task working from a script, then your ssh call becomes much simpler and should encounter fewer problems:
ssh myname#remotehost1 '/path/to/script'
For easily updating this script, you can write a short script for your local machine that uploads the most recent version via scp and then uses ssh to invoke it.
Note that when you run:
#!/bin/sh
ssh myname#remotehost1 'sudo -u webservice_username -i ; export P4USER=myname; cd dir ; p4 sync ; cd bin ; ./prog --domain=config_file restart ; tail -f ../logs/service.log'
Your ssh session runs sudo -u webservice_username -i waits for it to exit and then runs the rest of the commands; it does not execute sudo and then run the commands following. This has to do with the context in which you're running the series of commands. All the commands get executed in the shell of myname#remotehost1 and all sudo -u webservice_username - i is starts a shell for webservice_username and doesn't actually run any commands.
Really the best solution here is like bta said; write a script and then rsync/scp it to the destination and then run that using sudo.
export command simply not working with ssh like this, what you want to do is remote modify ~/.bashrc and it will source itself each time u do ssh login.

Cannot execute binary file error

I've got a shell script which I am trying to run as a specific user. My command looks like this:
su - jetty sh ./runProgram.sh
When I attempt to run this command through the console I get an error saying:
/bin/sh: /bin/sh: cannot execute binary file
I also tried:
su - jetty sh runProgram.sh
And I still get the same error..
It DOES work if I do this:
sh runProgram.sh
But this shell script is meant to be run by a specific user. Any advice on how to get this working??
Try
su - jetty -c sh runProgram.sh
According to su's documentation (info coreutils 'su invocation'), it will by default execute a shell, and the arguments to su are passed as arguments to the shell.
The implication is simply this: su is doing in essence:
/bin/sh *arguments_to_su*
but it does it as another user (the "effective user id")... that's all... So
su - jetty sh ./runprogram.sh
is akin to
(become the user jetty via login or su)
/bin/sh sh ./runprogram.sh
...and the shell will report an error, because the first /bin/sh, called by su, is trying to run the program sh as a shell script, with ./runprogram.sh as its argument. But sh itself is not a shell script, it is a binary (whose job it is is to run shell scripts).
if you were to simply do this:
su - jetty ./runprogram.sh
Then the su command will call /bin/sh with the program ./runprogram.sh as its argument, and jetty as the effective user id, and all should be well. ...SHOULD be well, because since you are doing an su - you are making the shell a login shell and changing to the user's home directory. If runprogram.sh is not in the home directory, you will get an error.
This is why, also, you cannot run for example run a cp command by simply:
su - jetty cp file1 file2
...because, again, after su changes effective user id to jetty it will try this:
/bin/sh cp file1 file2
...and cp is not a shell script. But the -c option works in this case; because you are telling su that you want to run /bin/sh with the -c option to the shell:
su - jetty -c "cp file1 file2"
does the job. Note that you must quote the command, because the entire string is passed to the shell and (I believe) any following arguments are ignored.
Finally, the previous poster's answer doesn't work for me on Linux, it requires the entire command string to be quoted.

Resources