Send command inside screen from an other user via bash - linux

Lets say:
I have 2 users: root and mc.
I want to run a command inside a screen which is located on mc, but i need to run the script as root.
This is what I came up with:
sudo -u mc -H sh -c "screen -r lobby -p 0 -X stuff "restart $(printf '\r')""
I guess, using 2 ' " ' wont work, so how do I manage this problem?

If you use double quote inside a double quoted string, just add \ in front of it to skip it.
sudo -u mc -H sh -c "screen -r lobby -p 0 -X stuff \"restart $(printf '\r')\""

Related

Unix: 'su user' not working and remains root inside SSH if condition [duplicate]

I've written a script that takes, as an argument, a string that is a concatenation of a username and a project. The script is supposed to switch (su) to the username, cd to a specific directory based upon the project string.
I basically want to do:
su $USERNAME;
cd /home/$USERNAME/$PROJECT;
svn update;
The problem is that once I do an su... it just waits there. Which makes sense since the flow of execution has passed to switching to the user. Once I exit, then the rest of the things execute but it doesn't work as desired.
I prepended su to the svn command but the command failed (i.e. it didn't update svn in the directory desired).
How do I write a script that allows the user to switch user and invoke svn (among other things)?
Much simpler: use sudo to run a shell and use a heredoc to feed it commands.
#!/usr/bin/env bash
whoami
sudo -i -u someuser bash << EOF
echo "In"
whoami
EOF
echo "Out"
whoami
(answer originally on SuperUser)
The trick is to use "sudo" command instead of "su"
You may need to add this
username1 ALL=(username2) NOPASSWD: /path/to/svn
to your /etc/sudoers file
and change your script to:
sudo -u username2 -H sh -c "cd /home/$USERNAME/$PROJECT; svn update"
Where username2 is the user you want to run the SVN command as and username1 is the user running the script.
If you need multiple users to run this script, use a %groupname instead of the username1
You need to execute all the different-user commands as their own script. If it's just one, or a few commands, then inline should work. If it's lots of commands then it's probably best to move them to their own file.
su -c "cd /home/$USERNAME/$PROJECT ; svn update" -m "$USERNAME"
Here is yet another approach, which was more convenient in my case (I just wanted to drop root privileges and do the rest of my script from restricted user): you can make the script restart itself from the correct user. This approach is more readable than using sudo or su -c with a "nested script". Let's suppose it is started as root initially. Then the code will look like this:
#!/bin/bash
if [ $UID -eq 0 ]; then
user=$1
dir=$2
shift 2 # if you need some other parameters
cd "$dir"
exec su "$user" "$0" -- "$#"
# nothing will be executed beyond that line,
# because exec replaces running process with the new one
fi
echo "This will be run from user $UID"
...
Use a script like the following to execute the rest or part of the script under another user:
#!/bin/sh
id
exec sudo -u transmission /bin/sh - << eof
id
eof
Use sudo instead
EDIT: As Douglas pointed out, you can not use cd in sudo since it is not an external command. You have to run the commands in a subshell to make the cd work.
sudo -u $USERNAME -H sh -c "cd ~/$PROJECT; svn update"
sudo -u $USERNAME -H cd ~/$PROJECT
sudo -u $USERNAME svn update
You may be asked to input that user's password, but only once.
It's not possible to change user within a shell script. Workarounds using sudo described in other answers are probably your best bet.
If you're mad enough to run perl scripts as root, you can do this with the $< $( $> $) variables which hold real/effective uid/gid, e.g.:
#!/usr/bin/perl -w
$user = shift;
if (!$<) {
$> = getpwnam $user;
$) = getgrnam $user;
} else {
die 'must be root to change uid';
}
system('whoami');
This worked for me
I split out my "provisioning" from my "startup".
# Configure everything else ready to run
config.vm.provision :shell, path: "provision.sh"
config.vm.provision :shell, path: "start_env.sh", run: "always"
then in my start_env.sh
#!/usr/bin/env bash
echo "Starting Server Env"
#java -jar /usr/lib/node_modules/selenium-server-standalone-jar/jar/selenium-server-standalone-2.40.0.jar &
#(cd /vagrant_projects/myproj && sudo -u vagrant -H sh -c "nohup npm install 0<&- &>/dev/null &;bower install 0<&- &>/dev/null &")
cd /vagrant_projects/myproj
nohup grunt connect:server:keepalive 0<&- &>/dev/null &
nohup apimocker -c /vagrant_projects/myproj/mock_api_data/config.json 0<&- &>/dev/null &
Inspired by the idea from #MarSoft but I changed the lines like the following:
USERNAME='desireduser'
COMMAND=$0
COMMANDARGS="$(printf " %q" "${#}")"
if [ $(whoami) != "$USERNAME" ]; then
exec sudo -E su $USERNAME -c "/usr/bin/bash -l $COMMAND $COMMANDARGS"
exit
fi
I have used sudo to allow a password less execution of the script. If you want to enter a password for the user, remove the sudo. If you do not need the environment variables, remove -E from sudo.
The /usr/bin/bash -l ensures, that the profile.d scripts are executed for an initialized environment.

How to "setup" screen using a bash script

I'm trying to write a bash script to create a screen (software) session with a specific set of windows, and cd to specific directories on each one.
Here is the script I have so far:
#!/bin/bash
killall screen;
screen -AmdS work;
screen -S work bash -c "cd myDir";
The problem is that I can't seem to change directories on that session. After running this script, I run $ screen -r and the current directory is still my default directory (~/).
(I've tried changing the cd command to touch myFile and the file is there after I run the script)
Try the following, it will open a new screen session with a bash which will change the directory and open a new bash with this directory as current:
screen -S work bash -c 'cd myDir && exec bash'
Adding -d -m to run it in detached mode. And after reattaching you will be in myDir:
screen -S work -d -m bash -c 'cd myDir && exec bash'
Better solution
The following code will create a detached screen with 3 screens each running myCommand1/2/3 in directory myDir1/2/3.
cd myDir1
screen -S work -d -m
screen -S work -X exec myCommand1
screen -S work -X chdir myDir2
screen -S work -X screen
screen -S work -X exec myCommand2
screen -S work -X chdir myDir3
screen -S work -X screen
screen -S work -X exec myCommand3
cd -
Note the last cd - that will return you back to your original working directory.
Finally just use screen -r work to attach your running screen session.
You can save the command line you want to run (including the final newline) into a register and paste it into the screen input:
screen -S work -X register c $'cd myDir\n'
screen -S work -X paste c

Bash script with multiple sudo commands in tabs

I have a bash script that opens a mate-terminal with 3 tabs, each tab having a command that requires sudo. The problem is that I have to put in my sudo password on each of the 3 tabs, which is not ideal. Can I make it so I only have put in my sudo password once? Basically, I want to double click the shell script, put in my sudo password once, and have all 3 commands execute. How can I do this? This script looks like this:
#!/bin/sh
mate-terminal \
--tab -e "sudo /sbin/mgetty -s 115200 -D /dev/ttyUSB0" \
--tab -e "sudo tail -f /var/log/mgetty/mg_ttyUSB0.log" \
--tab -e "sudo tail -f /var/log/messages"

Execute command on specific screen on CentOS

I use screen on CentOS to run my script. Example:
Output command screen -ls:
There is a screen on:
session-1 (Detached)
1 Socket in /var/run/screen/S-root
And I Run:
screen -r -S "session-1" -d -m -p 0 /tmp/script1.sh
screen -r -S "session-1" -d -m -p 1 /tmp/script2.sh
screen -r -S "session-1" -d -m -p 2 /tmp/script3.sh
but it's not work. I want script1.sh run on screen:0, script1.sh run on screen:1, script1.sh run on screen:2,... with option -p <screen number>. But it's not work. Please help me.
Thanks!
i have 10 window in session-1 and i want to run 10 script.
Since session-1 and its windows have already been created, we don't need options -d -m. Also, of options -r -S we need only one. To execute a program in an already existing session we need option -X exec …. So, the resulting commands would be like:
screen -r session-1 -p 0 -X exec /tmp/script1.sh
But when I tried this with screen versions 4.0, the program was executed in the current (last used) window, not in the window specified by -p. Apparently -p doesn't work with -X. What did work was:
screen -r session-1 -p 0 -X stuff /tmp/script1.sh$'\n'
screen -r session-1 -p 1 -X stuff /tmp/script2.sh$'\n'
screen -r session-1 -p 2 -X stuff /tmp/script3.sh$'\n'

Multiple commands in sudo over ssh in shell script

My script is as below.
#!/bin/bash
version = 1.1
echo "Enter username"
read UserName
ssh -t $UserName#server bash -c " '
./runSomeScript
echo "Entering Sudo"
sudo -s -u user1 -c "cd random; ./randomscrip xx-$version-yy"
'"
But this is not working.
Basically i want to do a ssh to a account. And then runSomeScript
Then do a sudo with user as user1 and then run commands cd random and ./randomscrip (with xx-Version-yy as argument) as the sudo user only.
But the commands inside sudo are not working.
Your quoting is a little careless. You're using double-quotes for the first and third levels of quoting, and the shell can't tell one from the other. Do something like this instead:
sudoScript="cd random; ./randomscrip xx-${version}-yy"
sshScript='
./runSomeScript
echo "Entering Sudo"
sudo -s -u user1 bash -c '"'${sudoScript}'"'
'
ssh -t ${UserName}#server "${sshScript}"
But beware that if you embed any single-quotes, it will still go wrong unless you add a layer of shell-quoting.
Finally, remove the spaces around = when you assign to version.

Resources