How do I fix 'WriteMessage: Bad file descriptor' of screen -r name? - gnu-screen

When I try to resume a screen session with
$ screen -r name
I get
WriteMessage: Bad file descriptor
How can I fix that? (Ideally being able to resume the screen, but at least remove it if resuming is not possible)
The problem why it occurs might be that the SSH connection was interrupted.

This worked for me:
Find the process's pid by running screen -R
Use screen -r <pid> instead of screen -r <name>
If the screen didn't detach from previous ssh session, you might also need to kill dead sshd process.

I got this error when trying to detach all screens with screen -D. I had attached the screen with
screen -R screen-name-here
To detach, I needed to specify the screen name:
screen -D screen-name-here

Related

Difference between screen flags -r and -x

What exactly is the difference between screen -x and screen -r. I know they're both for reattaching to the screen, but not sure I grasp when to use one or the other.
-r attaches a detached session, while -x attaches an attached session without detaching it, so it runs in both the places at the same time. Another useful option combination is -d -r which detaches a session if needed first and then reattaches it.

How to use screen to issue a command in the background over an ssh session

I am used to using linux terminals and nohup over ssh to issue commands that run in the background even when logged out of the ssh session. For some reason nohup seems to be broken in the latest MACOS. For that reason I am trying to executing this small sample script using screen command.
sleep 10
echo "this is my test file" > testfile
This file is saved as tst script. And then I issue the following command.
ssh sohaib#localhost screen -dm sh testscript
However nothing happens. screen just exits quietly without writing to the file testfile.
If I run this without ssh it works as desired. What am I doing wrong here?
The issue is that after your script exits the screen exits. The -dm is for deamons, i.e., scripts that keep running.
Showing the screen exiting after 10 seconds:
On remote host (file is executable):
ttucker#merlin:~$ cat test.sh
#!/bin/bash
echo derp > /tmp/test.txt
sleep 10
Command on local machine:
[ttucker#localhost ~]$ ssh ttucker#merlin 'screen -dmS my_screen ~/test.sh'
After run.
On remote machine, a few seconds after screen is running:
ttucker#merlin:~$ screen -ls
There is a screen on:
23141.my_screen (11/21/2016 07:05:11 PM) (Detached)
1 Socket in /var/run/screen/S-ttucker.
On remote machine, over 10 seconds later:
ttucker#merlin:~$ screen -ls
No Sockets found in /var/run/screen/S-ttucker.
Modifying the script to keep running, and so, keeping the screen up:
If you are really running a script that needs to stay up you can do the following in the script:
#!/bin/bash
while true; do
# Do something
sleep 10
done
This will do something, wait 10 seconds, then loop again.
Or, detaching the screen manually:
You can ssh to the remote machine, run screen, then press Ctrl+A,D, press Ctrl and hold, then hit A then hit D. You can now exit the SSH session and the screen will stay running.

bash script for screen -r

I want to make a bash script that echo's something into one of the screens that I have running (screen -r is how I get to it in SSH).
I was wondering how I would make the script execute itself in screen -r?
I basically just want the script to say something on a minecraft server through the console and would set up a cronjob to say it every x minutes.
Cheers,
You can use the -X option of screen to send commands to a running screen session.
Also the -p option is useful in this case, as you can use it to preselect a window
As an example you can run a script in a running screen session on windows 0 via:
screen -p 0 -X stuff './fancy_script.sh^M'
Note, that you have to append the return key-code to execute the script.
You can look in /dev/pts. I don't have screen here to test, but you can echo something to an opened terminal with, for example, echo "toto" > /dev/pts/0 (it will be echoed on the first opened terminal).

running command on remote machine using ssh

i want to run some command on several machine using ssh. I know it can be done by just using the command "ssh user#hostname command". However, the command i want to run print some string on the console. Is there any way that send all the strings back to the console that i'm on?
You could run the commands in a screen:
screen -S test
ssh user#hostname command1
ssh user#hostname2 command2
You can then detach (Ctrl-D) from the screen, let it run for however long it will run, then re-attach (screen -r test) to the screen and see all of the output. This assumes that you won't have a ton of output from the commands, however. Here's a link to a tutorial on screen.
ssh user#hostname command
Does just that. if 'command' outputs something, it'll show on the terminal you ran ssh from.
Try e.g. ssh user#hostname ls -l
But as others have said, GNU screen is invaluable for this type of work.
You probably want to use Gnu Screen for this. You can start a process in a "virtual" terminal, "detach" the terminal and log out for however long you want... Then you can ssh back in and re-attach the terminal to see the console output.
Also have a look at nohup, for example:
ssh user#domain.com nohup script_that_outputs_strings.py > the_strings.txt
Then if you want to go back and monitor the progress, you could check back and tail the file or scp the output back to your local machine.
Why don't you send you an email back?
Or use a log file, and scp it to your current computer?
otherwise, I don't know!

How do I execute a command every time after ssh'ing from one machine to another?

How do I execute a command every time after ssh'ing from one machine to another?
e.g
ssh mymachine
stty erase ^H
I'd rather just have "stty erase ^H" execute every time after my ssh connection completes.
This command can't simply go into my .zshrc file. i.e. for local sessions, I can't run the command (it screws up my keybindings). But I need it run for my remote sessions.
Put the commands in ~/.ssh/rc
You can put something like this into your shell's startup file:
if [ -n "$SSH_CONNECTION" ]
then
stty erase ^H
end
The -n test will determine if SSH_CONNECTION is set which happens only when logged in via SSH.
If you're logging into a *nix box with a shell, why not put it in your shell startup?
.bashrc or .profile in most cases.
Assuming a linux target, put it in your .profile
Try adding the command below the end of your ~/.bashrc. It should be exited upon logoff. Do you want this command only executed when logging off a ssh session? What about local sessions, etc?
trap 'stty erase ^H; exit 0' 0
You probably could setup a .logout file from /etc/profile using this same pattern as well.
An answer for us, screen/byobu users:
The geocar's solution will not work as screen will complain that "Must be connected to a terminal.". (This is probably caused by the fact that .ssh/rc is processed before shell is started. See LOGIN PROCESS section from man 8 sshd).
Robert's solution is better here but since screen and byobu open it's own bash instance, we need to avoid infinite recursion. So here is adjusted byobu-friendly version:
## RUN BYOBU IF SSH'D ##
## '''''''''''''''''' ##
# (but only if this is a login shell)
if shopt -q login_shell
then
if [ -n "$SSH_CONNECTION" ]
then
byobu
exit
fi
fi
Note that I also added exit after byobu, since IMO if you use byobu in the first place, you normally don't want to do anything outside of it.