keyboard IO broken after reattach to tmux/screen - r

After reattaching a screen or tmux session over ssh, I commonly encounter two issues:
vim tab completion is broken. :e <Tab> produces :e ^I instead of suggesting files. Same for tags (:tj). Closing and re-opening vim fixes this, but at the cost of losing vim state.
R cannot produce graphics. I have X11 forwarding (ssh -X -Y) enabled. Closing and re-opening does not help.
I cannot deliberately reproduce the problem by closing my ssh window and re-attaching. Problem is usually observed after long periods without network connectivity between reattaching, and usually detaching is abrupt (loss of network connectivity).

Vim tab completion:
This is an issue with screen/tmux's terminal emulator. If tabs work in your shell (e.g. bash), that's likely to the shell's credit; it knew to map the control sequence for you while vim did not. Presumably, you could fix this in vim in a similar manner, but then you'd run into the issue in some other interactive program.
I can't speak to tmux, but for screen, you should look to update your ~/.screenrc. Mine, copied from the default that ships with Redhat (which I no longer use...), includes this:
#xterm understands both im/ic and doesn't have a status line.
#Note: Do not specify im and ic in the real termcap/info file as
#some programs (e.g. vi) will not work anymore.
termcap xterm hs#:cs=\E[%i%d;%dr:im=\E[4h:ei=\E[4l
terminfo xterm hs#:cs=\E[%i%p1%d;%p2%dr:im=\E[4h:ei=\E[4l
Heed that comment, it may indicate your issue.
Another reference to vi, which may or may not have come from Redhat's screenrc, is:
# Yet another hack:
# Prepend/append register [/] to the paste if ^a^] is pressed.
# This lets me have autoindent mode in vi.
register [ "\033:se noai\015a"
register ] "\033:se ai\015a"
bind ^] paste [.]
Hopefully one or both of these will help, or else I've pointed you in the right direction to research what you need to correct your screen/tmux terminal emulation. Perhaps the answers to screen, vimrc, and bashrc over at LinuxQuestions.org can help further.
X11 Forwarding:
When you first launch screen, the $DISPLAY is inherited. For example, I take advantage of this on my TV server; I launch screen locally (DISPLAY=localhost:0), then when I connect to it over SSH, anything I do regarding X pops up on the TV. Obviously, this is not at all your use case; I'm just trying to educate you on how it works so you can understand the solution.
If you are reconnecting to a screen/tmux session launched by an old SSH connection, you may luck out and have it connected to the same X display (SSH defaults to localhost:10.0 and then increments each time it finds a collision), but that doesn't sound like it's happening for you. (The "localhost" part is optional, as is the ".0" part. Those shouldn't matter for your purposes. DISPLAY=:10 is the same as DISPLAY=localhost:10.0)
Before you connect to your screen/tmux session, take a look at your $DISPLAY.
$ echo $DISPLAY
localhost:10.0
Then, log into screen/tmux and set the $DISPLAY to what you saw before.
$ screen -r
$ export DISPLAY=localhost:10.0
I don't think either screen or tmux are smart enough to go any farther than this (think of my TV server example; this isn't always desired, and asking screen/tmux to test the $DISPLAY and then act contingent on its availability is a bit much), so you have to do this manually.
(This may be annoying if you're like me and add screen -r >/dev/null 2>&1 in your ~/.bashrc. I don't run into this issue because I try to avoid X11 forwarding whenever possible due to its being slow as molasses and of course not surviving SSH disconnections.)

The second problem looks like a DISPLAY variable one. Try
echo $DISPLAY when you first login and again when you reattach the session.
if they differ (which is what i suspect), setenv or export it to the correct value.
As for the first problem try taking a look at your tmux.conf (or the default from your install)
cause they were remapping
<TAB> to funny actions in the development versions (like clear-history) so maybe
after the reattach, tmux owns the event and not vim.

Related

Is there any portable or at least vendor-specific way to detect if a Unix socket is orphaned?

When a process creates UDS and exits abnormally, it leaves a socket file behind. On the next run, the program may have troubles seeing the file already exists.
Is there any way to detect if a socket file is orphaned? The best way should be POSIX and available on any UNIX brand, but something Linux/FreeBSD/Solaris/whatever-specific is of use as well.
I'm not asking on how to
make /tmp get cleared on reboot. Sometimes app crash without reboot.
use any GUI or even command-line tool to check it manually.
remove list of files before running a program or put an unlink before bind.
Well, looks like I was just one step from the answer.
There is nothing like SO_REUSEADDR for UDS, and I do believe that's for good reason
There is a way to guard socket file with lock file, which is a (relatively) clean and sane way
Using /tmp/socket.lock to guard a /tmp/socket, we have to
open it with O_RDONLY | O_CREAT
flock it with LOCK_EX | LOCK_NB
and never do anything with the guard. If flock is successful on next run, than no process hold the lock file, resp., no process use the socket. We are ok to remove it.
Of course, we assume that every program using the socket uses the protocol as well.
Details are at Victor Gadov's github, copied here due to fragile nature of links in Internet.

What is the status of long-running remote R sessions in ESS/Emacs?

I routinely run R remotely and have had great success with RStudio server to do so. However, Emacs/ESS is still preferable in many cases, particularly since I often work on multiple projects simultaneously. What is the start-of-the-art when running ESS/R in emacs when the expectation is that the connection will be broken? To be more concrete, I'd love to run a tmux session in Emacs so that I can connect to a long-running R session running in tmux (or screen). What is the status of ESS/Emacs to support such a scenario? This seems to be changing over time and I haven't found the "definitive" approach (perhaps there isn't one).
I do that all the time. At both home, and work.
Key components:
Start emacs in daemon mode: emacs --daemon &. Now emacs is long-running and persistent as it is disconnected from the front-end.
Connect using emacsclient -nw in text mode using tmux (or in my case, the byobu wrapper around tmux). As tmux persists, I can connect, disconnect, reconnect,... at will while having several tabs, split panes, ... from byobu/tmux.
When nearby -- on home desktop connecting to home server, or at work with several servers -- connect via emacsclient -c. Now I have the standard X11 goodness, plotting etc pp. That is my default 'working' mode.
But because each emacs session has an R session (or actually several, particularly at work) I can actually get to them as I can ssh into the tmux/byobu session too.
Another nice feature is tramp-mode allowing you to edit a remote file (possibly used by a remote R session) in a local Emacs buffer as tramp wraps around ssh and scp making the remote file appear local.
Last but not least mosh is very nice on the (Ubuntu) laptop as it automagically resumes sessions when I am back on the local network at home or work. In my case mosh from Debian/Ubuntu on server and client; may also work for you OS X folks.
In short, works like a dream, but may require the extra step of "disconnecting" emacs from the particularly tmux shell in which you launch. Daemon mode is key. Some of these sessions run on for weeks.
I started working like this maybe half a decade ago. Possibly longer. But using ESS to connect to remote Emacs session is much older -- I think the ESS manual already had entries for it when I first saw it in the late 1990s.
But I find this easier as it gives me "the whole emacs" including whatever other buffers and session I may need.
Edit: And just to be plain, I also use RStudio (Server) at home and work, but generally spend more time in Emacs for all the usual reasons.
More Edits: In follow-up to #kjhealy I added that I am also a fan of both tramp-mode (edit remote files locally in Emacs thanks to the magic that are ssh and scp) as well as mosh (sessions that magically resume when I get to work or back home).

How to detach a process from terminal in unix?

When I start a process in background in a terminal and some how if terminal gets closed then we can not interact that process any more. I am not sure but I think process also get killed. Can any one please tell me how can I detach that process from my terminal. So even if I close terminal then I can interact with same process in new terminal ?
I am new to unix so your extra information will help me.
The command you're looking for is disown.
disown <processid>
This is as close as you can get to a nohup. It detaches the process from the current login and allows it to continue running. Thanks David Korn!
http://www2.research.att.com/~gsf/man/man1/disown.html
and I just found reptyr which lets you reparent a disowned process.
https://github.com/nelhage/reptyr
It's already in the packages for ubuntu.
BUT if you haven't started the process yet and you're planning on doing this in the future then the way to go is screen and tmux. I prefer screen.
You might also consider the screen command. It has the "restore my session" functionality. Admittedly I have never used it, and forgot about it.
Starting the process as a daemon, or with nohup might not do everything you want, in terms of re-capturing stdout/stdin.
There's a bunch of examples on the web. On google try, "unix screen command" and "unix screen tutorial":
http://www.thegeekstuff.com/2010/07/screen-command-examples/
GNU Screen: an introduction and beginner's tutorial
First google result for "UNIX demonizing a process":
See the daemon(3) manpage for a short overview. The main thing of daemonizing
is going into the background without quiting or holding anything up. A list of
things a process can do to achieve this:
fork()
setsid()
close/redirect stdin/stdout/stderr to /dev/null, and/or ignore SIGHUP/SIGPIPE.
chdir() to /.
If started as a root process, you also want to do the things you need to be root
for first, and then drop privileges. That is, change effective user to the "daemon"
user or "nobody" with setuid()/setgid(). If you can't drop all privileges and need
root access sometimes, use seteuid() to temporary drop it when not needed.
If you're forking a daemon then also setup child handlers and, if calling exec,
set the close on exec flags on all file descriptors your children won't need.
And here's a HOWTO on creating Unix daemons: http://www.netzmafia.de/skripten/unix/linux-daemon-howto.html
'Interact with' can mean a couple of things.
The reason why a program, started at the command-line, exits when the terminal ends, is because the shell, when it exits, sends that process a HUP signal (see documentation for kill(1) for some introduction; HUP, by the way, is short for 'hang up', and originally indicated that the user had hung up the modem/telephone). The default response to a HUP signal is that a process is terminated – that is, the invoked program exits.
The details are slightly more fiddly, but this is the general intuition.
The nohup command tells the shell to start the program, and to do so in a way that this HUP signal is ignored. That is, the program keeps going after the invoking terminal exits.
You can still interact with this program by sending it signals (see kill(1) again), but this is a very limited sort of interaction, and depends on your program being written to do sensible things when it receives those signals (signals USR1 and USR2 are useful things to trap, if you're into that sort of thing). Alternatively, you can interact via named pipes, or semaphores, or other bits of inter-process communication (IPC). That gets fiddly pretty quickly.
I suspect what you're after, though, is being able to reattach a terminal to the process. That's a rather more complicated process, and applications like screen do suitably complicated things behind the scenes to make that happen.
The nohup thing is a sort of quick-and-dirty daemonisation. The daemon(3) function does the daemonisation 'properly', doing various bits of tidy-up as described in YePhIcK's answer, to comprehensively break the link with the process/terminal that invoked it. You can interact with that daemonised process with the same IPC tools as above, but not straightforwardly with a terminal.

Can't save the output of minicom into a file

When I use Minicom to capture data from a serial port, I need to save the big data into a file, named minicom.cap. However, if I press Ctrl+A and L to capture file, it failed. No file was created (minicom.cap did not exist beforehand). My download directory was properly created. My OS is Mint, and I read data from Arduino nano v3.0
Did you try to start minicom as
minicom -C capturefile
Unless i got something wrong, it should start to capture incoming data immediately.
OP might miss step "Shift + L" after writing, so the overall procedure is as below:
1 (inside minicom)
2 Ctrl A + Z
3 Shift + L
4 (wait for writing ... )
5 Shift + L
6 (check the file you have written, default is minicom.cap, you may want to find it at /root/minicom.cap)
chown root:dialout /etc/minicom/minirc.dfl
chmod 664 /etc/minicom/minirc.dfl
Now any member of the dialout group can write to minirc.dfl
minicom needs a configuration file that is under root permissions and is stored at /etc/minicom/ and is named minirc.dfl.
Usually when you first run minicom for the first time, as sudo, you can save the minirc.dfl, as if you run as any other user it will not save.
That may be your problem.
This is a little more than the scope of the question calls for but as it has already been answered, I thought somebody might like to do things a little user friendly.
You might be interested in this if you frequently open up a serial connection to multiple devices. You can do this with desktop shortcuts.
I use this for switch and router connections, I have two different console cables, a USB to mini USB and also a db9 with USB A adapter to rj45.
Using the shortcuts here means I don't need to manually reconfigure minicom every time I want to switch devices. The shortcuts give the correct configuration file as a parameter (identifier) as well as the capture file (-C). All i need to do it make sure my devices are connected to my computer with the cables.
If this is something you could use, run these commands as a normal user from your terminal (not from minicom). The configuration files will be saved to your home directory where minicom can find them.
Make a log file directory: You might choose to just log in /var/log but I want quick access to the log files.
mkdir ~/minicom
Find your device:
dmesg | grep tty
If your cable uses an RS-232 chip such as some usb to mini usb console cables, your tty device will likely be on ttyACM* and not ttyUSB*
Create the minicom configuration file using nano. Adapt the capitalised parts to fit your needs, baudrate may be set incorrectly if you get quirky characters or no output. You may create as many as you need along with the desktop shortcuts. just change the identifier.
nano ~/.minirc.IDENTIFIER
pu port /dev/ttyDEVICE
pu baudrate 9600
pu rtscts No
pu logfname /home/USER/minicom/IDENTIFIER.log
Create a desktop shortcut.
nano ~/Desktop/IDENTIFIER.desktop
[Desktop Entry]
Encoding=UTF-8
Name=Minicom IDENTIFIER
Comment=Something relevant to your connection/device name maybe
Exec=minicom IDENTIFIER -C/home/USER/minicom/IDENTIFIER.log
Terminal=1
Type=Application
Make it executable
chmod +x ~/Desktop/IDENTIFIER.desktop
That's it now test the connection, double click your new shortcut.
A note about the IDENTIFIER part, it can be anything. a router or switch model, a device name or type. Do what suits you but maybe use hyphens instead of spaces, I've not tested that but i would imagine they would cause issues such as only getting the name before the first space or worse, attempting to load multiple minicom.identifier files.
Once you have created your first connection, open another terminal:
tail -fn25 ~/minicom/IDENTIFIER.log
Because you have set minicom to capture output, by tailing the log/capture file you can scroll back as far as you need should you be running things with lengthy output, It can be useful for configuration files in routers/switches for example which can be thousands of lines long. Just scroll to the part you are working on in the tailed file to use as a reference while you make changes in minicom, the tail terminal will still collect data but will not automatically jump back to the new line as minicom does when you star to type.
If somebody more shell savvy than myself would like to add to this to make a shell script that accepts the required parameters for setting up a new connection profile,logs etc I wouldn't be too upset about it :)
As an aside, I wanted to add a command prior to minicom running in the shortcut to apply a title to the terminal window using the identifier, I could not get this to work in Ubuntu 20.04 at the time of this posting.

Proper way to exit command line program?

I'm using mac/linux and I know that ctrl-z stops the currently running command in terminal, but I frequently see the process is still running when i check the system monitor. What is the right way to stop a command in terminal?
Typically I run into this issue when running python or ruby apps, i'm not sure if that has something to do with it, just thought I would add that.
Using control-z suspends the process (see the output from stty -a which lists the key stroke under susp). That leaves it running, but in suspended animation (so it is not using any CPU resources). It can be resumed later.
If you want to stop a program permanently, then any of interrupt (often control-c) or quit (often control-\) will stop the process, the latter producing a core dump (unless you've disabled them). You might also use a HUP or TERM signal (or, if really necessary, the KILL signal, but try the other signals first) sent to the process from another terminal; or you could use control-z to suspend the process and then send the death threat from the current terminal, and then bring the (about to die) process back into the foreground (fg).
Note that all key combinations are subject to change via the stty command or equivalents; the defaults may vary from system to system.
if you do ctrl-z and then type exit it will close background applications.
Ctrl+Q is another good way to kill the application.
Take a look at Job Control on UNIX systems
If you don't have control of your shell, simply hitting ctrl + C should stop the process. If that doesn't work, you can try ctrl + Z and using the jobs and kill -9 %<job #> to kill it. The '-9' is a type of signal. You can man kill to see a list of signals.

Resources