I have seen some similar questions asked but the solutions don't seem to work in my case.
I am trying to SSH into a specific screen instance on a Node machine and then execute some commands
My current process is this:
On the remote machine I create a screen instance:
screen -dmS "my_screen"
From my local machine I do something like:
ssh <user>#<remote> -a -x -t screen -x -r my_screen -X stuff 'ruby my_script.rb'
but the output is just:
Connection at (ip) closed.
and the ruby script is not run.
If I separate the commands then the script runs correctly eg:
ssh <user>#<remote> -a -x -t screen -x -r my_screen
it connects to the screen, and then I manually enter:
ruby my_script.rb
exit
Then the script executes in the screen as intended.
What is the correct way to send commands to a screen?
In your second example, you are executing the command by typing it into the console. If that is the behavior you want to emulate, you can use the stuff command to have screen paste your text into the console to execute it.
ssh <user>#<remote> -a -x -t screen -x -r my_screen -X stuff \"ruby my_script.rb^M\"
(Note the ^M was generated using CTRL-V, CTRL-M).
This won't display anything to your open terminal, but when you reconnect to the screen, you should see the output of your command (assuming the screen was at a console window at the time you sent the command, which is the risk with this approach).
You should be using exec instead of stuff. As the name implies, exec executes commands inside the screen
ssh <user>#<remote> -a -x -t screen -x -r my_screen -X exec ruby myscript.rb
Related
I want to create a small startup script that does multiple things in a row in a screen.
The script starts a named, detached screen (screen -S discordbot -d -m works)
The user inside the script is changed (Neither screen -S discordbot -X "su discordbot", screen -S discordbot -X su discordbot, nor screen -S discordbot -d -m bash -c "su discordbot;" seems to work, or at least subsqeuent commands are not executed).
A cd folder change is exectuded.
A java jar or other script is started.
As I run multiple bots, the script needs to be able to do this in slight variation multiple times in a row. Any pointers on how this could be done?
The screen session that you start up will exit as soon as the process that you started exits.
This works, for instance:
$ screen -S discordbot -d -m bash
$ screen -ls
There is a screen on:
2948.discordbot (Detached)
1 Socket in <...>
As does this:
$ screen -S discordbot -d -m bin/discordbot.sh
Where bin/discordbot.sh looks like this:
#!/bin/sh
echo "Sleeping..."
sleep 10
/bin/echo -n "Hit enter to finish this script: "
read
The last two lines to prevent the screen from exiting prematurely. The other various things you want to do within that startup script should also work, assuming that you do this as root so that the su will work without prompting.
Was wondering how I can start up a command such as:
while :; do ./myCommand; done;
But instead of doing the usual
screen -S nameOfMyScreen
Then the command
while :; do ./myCommand; done;
Then detach the screen
^a ^d (Control "a" the control "d"
I would like it to start and detach. Thanks!
screen -d -m sh -c "while :; do ./myCommand; done;"
Explanation:
-d -m starts screen in detached mode (create session but don't attach to it)
sh -c commandline starts a shell which executes the given command line (necessary, since you are using the while builtin).
From screen -h, these look useful:
-dmS name Start as daemon: Screen session in detached mode.
-X Execute <cmd> as a screen command in the specified session.
I haven't done this myself, but that's where I'd start.
Update:
The top of the help also says
Use: path/to/screen [-opts] [cmd [args]]
so the -X switch may be to execute a screen command as opposed to a shell command. You might just be able to put your command after the -dmS <name> without any -X switch.
I use a script which after execution opens different tabs and connects to different servers(using ssh). Now along with that,I want to run another command (say 'pwd').So how to do that?
gnome-terminal --tab -e 'ssh user#ip1' --tab -e 'ssh user#ip2'
This opens 2 tabs and connects to corresponding ip.After ssh in every tab I want to run another command, so that there will be two tabs,and after connecting to ip it will run specified command
You need to use SSH ability to execute remote command, like this:
gnome-terminal --tab -e "ssh -A -t user#ipbridge \"ssh -t user#ip1 'pwd; /bin/bash -i'\""
Note the /bin/bash -i after the command. It is needed, because otherwise ssh will exit after the command.
Use ansible, fabric or any automation tool like any of these to do that you want. this tools allow execute a same command via ssh in multiple machines at same time in simple way.
using ansible you only need to do somthing like this
ansible <your-list-of machine> -m shell -a "your command"
example
ansible ip1 -m shell -a "echo $TERM"
I have a PHP script with a web interface which is used to provide input into a process which I am automating. In this process, I am attempting to include using SSH and screen to run some commands (all sent through PHP's exec).
I am currently using the following which is writing echo sent from script to the screen, but isn't executing it. I've tried adding the -ne option to echo and adding \n or ^M to the end. I've also tried changing around the types of quotes I'm using, but I'm having trouble getting the code to execute (sending enter).
ssh -t -t myUser#myDomain.com 'screen -r -d -S -X myScreen stuff "echo -ne sent from script"' 2>&1
How do I go about getting that code to execute?
This took much longer to figure out than I would like to admit. They key was adding a $ before the command sent to stuff and then using a \n to send the enter press.
I added an extra screen -list; to demonstrate how to send multiple commands before entering the screen. I also added an extra echo to demonstrate how to send multiple commands to the screen.
ssh -t -t myUser#myDomain.com "screen -list; screen -r -d -X -S myScreen stuff $'echo here; echo here\n'" 2>&1
I am running a script on a remote server. I ran the script in screen, however I need to stop it before it completes since I need to update the script. I can easily detach from screen, however, is there a way to kill a screen process?
CTRL+a and then 'k' will kill a screen session.
There are a couple of 'screen' ways to kill a specific screen session from the command line (non-interactively).
1) send a 'quit' command:
screen -X -S "sessionname" quit
2) send a Ctrl-C to a screen session running a script:
screen -X -S "sessionname" stuff "^C"
In both cases, you would need to use 'screen -ls' to find the session name of the screen session you want to kill ... if there is only one screen session running, you won't need to specify the -S "sessionname" parameter.
I used this to quit hundreds of erroneous screen sessions created by a buggy command:
for s in $(screen -ls|grep -o -P "1\d+.tty"); do screen -X -S $s quit; done;
where: the grep -o -P "1\d+.tty" is the command to get session names with Perl-like name regex "1\d+.tty" which captures all sessions start with number 1, has some other numbers (\d) and end with .tty
Warning:
You should test with this command first to see you get the exact list of sessions you want before apply the above command. This is to avoid quitting unwanted sessions:
for s in $(screen -ls|grep -o -P "1\d+.tty"); do echo $s; done;
I always to this echo test whenever the list in for loop is not clear, for example, the one generated by sub-command in $() expansion.
previous answers didn't work for me on a winputty terminal and amazon ssh server connection.. but this one does work:
screen -S yourscreentitlehere -X stuff $'\003'
references:
Sending ctrl-c to specific screen session
$'\003' is ctrl+c http://donsnotes.com/tech/charsets/ascii.html
stuff is https://www.gnu.org/software/screen/manual/screen.html#Paste
I am using putty, and it seems I am already in the screen and couldn't open and close. Every time I do "exit", I just close the putty window. Here is the termimal print
>>screen -r
21063.unlimited (11/08/20 15:45:19) (Attached)
24054.cure6 (11/08/20 09:46:13) (Attached)
There is no screen to be resumed.
and
screen -S 21063.unlimited -X stuff $'\003'
does not do anything.
I found that as simple as the following line works perfect
screen -x 21063.unlimited
it sends me back into the screen and from there "exit" works.
Note that it is lower-case -x