gvim pid in $! different to wmctrl list - linux

I have a script which launches multiple gvim windows. I want to position them in a certain way. wmctrl can do this, but because there are multiple instances, the window names are ambiguous. I figure: use pids.
gvim /tmp/xxx &
X=$!
wmctrl -lp | grep $X
echo $X
wmctrl -lp | grep GVIM
echo sleeping
sleep 3
wmctrl -lp | grep GVIM
The output is:
5211
sleeping
0x03400062 0 5218 localhost xxx (/tmp) - GVIM
It seems gvim starts out with pid 5211 but launches a new process for the actual window. Also, that process doesn't exist yet.
How can I unambiguously get the wmctrl window handle of the gvim instance I just started? Or should I use something else?
The --echo-wid option looks nice but I am using KDE.

I just ran into the same problem, and solved it by running
gvim -f &
pid=$!
just as n.m. suggested in the comments above.
The manpage of gvim sais:
-f Foreground. For the GUI version, Vim will not fork and detach from the
shell it was started in. On the Amiga, Vim is not restarted to open a new
window. This option should be used when Vim is executed by a program that
will wait for the edit session to finish (e.g. mail). On the Amiga the
":sh" and ":!" commands will not work.
which explains why it works.
I don't know if you tried this, or if the answer even matters anymore, but I hate leaving a good question unanswered :)
credit goes to n.m. for pointing out the -f switch

Related

how to make gvim hold terminal until it ends?

I am trying to find and replace over file hierarchy using gvim like this:
find . | xargs grep -l pattern | xargs -n 1 gvim -c "%s/pattern/replacement/gc" -c "wq"
I could probably try to make it work properly without the n flag, but I could have theoretically many, many files with matches. What happens now is that gvim dettaches from terminal, so xargs starts all instances of gvim one after another with little delay. If I could force gvim to hold terminal, xargs would wait for gvim to finish, thus there would ever only be one instance of gvim running.
Unfortunately I can't use vim in the environment that this is relevant to. I obtained a working binary for gvim from a colleague, but they did not have a vim binary and I failed to compile vim myself and gave up on it for now.
You're looking for the -f command-line option:
-f GUI: Do not disconnect from the program that started Vim.
'f' stands for "foreground". If omitted, the GUI forks a new
process and exits the current one. "-f" should be used when
gvim is started by a program that will wait for the edit
session to finish (e.g., mail or readnews). If you want gvim
never to fork, include 'f' in 'guioptions' in your |gvimrc|.

What happens when I launch something like "gedit" which returns the prompt immediately?

In CentOS7.2, when I launch gedit (/usr/bin/gedit the version is 3.14.3)
$ gedit hoge.txt
then the prompt returns immediately.
I am pretty new for UNIX world but where does the process go?
When I already have opened gedit, it looks gedit try opening a new tab in the existing window. That is why I cannot see the process by
$ ps (without x)
if the existing gedit is invoked in another shell.
I kind answered myself, but I want to ask how can it be done?
gedit deals with many technical process under the OS?
I realized
firefox
also looks similar.
In my case, gedit don't go to background when launched from terminal, but firefox does. So if I want to know what happens with firefox, I will run
ps -fu `whoami` | grep firefox
And look for its PID in the output (18235 in that case):
me 18235 1900 20 jul28 ? 22:58:52 /usr/lib/firefox/firefox
Then I will run pstree like this:
pstree -Ahps 18235
And the output of pstree will show me the processes tree for launched firefox
init(1)---lightdm(1272)---lightdm(1893)---init(1900)---firefox(18235)-+-plugin-containe(8990)-+-{plugin-containe}(8992)
| |-{plugin-containe}(8993)
| `-{plugin-containe}(8994)
|-{firefox}(18242)
|-{firefox}(18243)
|-{firefox}(18245)
|-{firefox}(18246)
|-{firefox}(18247)
It loks like firefox(18235) is attached to parent init(1900) who's attached to lightdm(1893), etc.

How can I launch multiple xterm windows and run a command on each, leaving each window open afterward?

I'm lazy, and I prefer that computers do my work for me. I ssh into several machines on a daily basis, so I created a simple script that launches some xterm windows and places them in positions I want (as you can see, I'm using bash):
#!/bin/bash
xterm -geometry 80x27+1930+0 &
xterm -geometry 80x27+2753+0 &
xterm -geometry 80x27+1930+626 &
xterm -geometry 80x27+2753+626 &
However, the next thing I do is go to the first window and type in
ssh server_a
then in the second
ssh server_b
and so on. What I'd like to do is have my script do the ssh commands in each xterm window, and then leave the windows open for me to do my work. I've seen the -e option for xterm, but the window closes after I execute my command. Is there a way to do this?
I apologize if this is a duplicate question. I've searched around and haven't had any luck with this. Many thanks!
I'd love to see a more elegant answer, but what I came up with does work:
xterm -e bash -c 'echo foo; exec bash'
Replace echo foo with the command of your choice, and you're good to go.
This answer gives one of the best answers I've seen so far to do this. Use the bash --init-file flag either in the shebang or when executing the terminal:
#!/bin/bash --init-file
commands to run
... and execute it as:
xterm -e /path/to/script
# or
gnome-terminal -e /path/to/script
# or
the-terminal -e bash --init-file /path/to/script/with/no/shebang
My only real complaint with the exec option is if the command executed prior to exec bash is long running and the user interrupts it (^C), it doesn't run the shell. With the --init-file option the shell continues running.
Another option is cmdtool from the OpenWin project:
/usr/openwin/bin/cmdtool -I 'commands; here'
# or
/usr/openwin/bin/cmdtool -I 'commands; here' /bin/bash
... where cmdtool injects the commands passed with -I to the slave process as though it was typed by the user. This has the effect of leaving the executed commands in the shell history.
Another option is to use gnome terminator. This creates and positions terminals interactively, and you can set up each terminal to run commands within terminator preferences.
Also does lots of extra tricks using keybindings for things like move, rotate, maximise/minimise of terminals within the containing terminator window
See: https://superuser.com/a/610048
"ClusterSSH controls a number of xterm windows via a single graphical console window to allow commands to be interactively run on multiple servers over an ssh connection"
https://github.com/duncs/clusterssh/wiki
$ cssh server_a server_b
$ command

Why does "locate filename | xargs vim" cause strange terminal behaviour?

When I do "locate 50local.policy | xargs vim", I get the error "Vim: Warnung: Die Eingabe kommt nicht von einem Terminal" (translation: Vim: Warning: The input does not come from a terminal).
I can edit successfully with vim but after I close it my terminal behaves strangely (I can't type letters and when I hit enter the shell prompt simply gets repeated.
When I do it with "xargs gedit" it does not create those problems.
I use Ubuntu 11.10 with Gnome 3 and Gnome-Terminal 3.0.1.
Vim expects to be connected to a real terminal and sends codes appropriate to that.
Reset the terminal with
reset
The easiest workaround:
locate 50local.policy | xargs gvim
Rationale gui vim doesn't require a terminal
Otherwise:
vim $(locate 50local.policy)
Rationale vim is started directly connected to the terminal (instead of as a child process under xargs which in turn runs in a subshell with stdin/stdout connected to pipes instead of a terminal). It is like saying
vim /usr/some/dir/50local.policy /usr/local/some/dir/50local.policy
Alternatively
You can dodge the issue by not starting vim with the arguments, but adding the arguments from vim! Vim is in fact a lot better at running shells than shells are at running vim.
Whilst in vim:
:args `locate 50local.policy`
:rewind
This sets the argument list to the files returned from the shell command between the ticks; :rewind then goes to the first file from that list.
If you were editing multiple matches, try this:
:w|next
This sequence of commands (separated by |) writes the current buffer to file, then goes to the next file in the args list.
An other alternative is to execute xargs with the -o option. From the man page:
-o Reopen stdin as /dev/tty in the child process before executing
the command. This is useful if you want xargs to run an interac-
tive application.
Note, -o is a BSD extension to xargs.
A more portable means to achieve the same effect is:
xargs sh -c 'vim "$#" < /dev/tty' vim
While 'reset' fixes the problem, you can also explicitely re-activate the echo behaviour with:
stty echo

tmux: hangs and do not load, and do not respond to any option command

I have installed tmux from source on my localspace in Fedora. It was working nicely so far. But suddenly can not run it anymore, when run tmux, it just halts. Tried different command options like ls-sessions, none works. Killed all the processes of my user, deleted all the files of tmux and libevnet, and reinstalled them again from scratch. Still same, and tmux command in terminal just freezes without any actual error.
I had faced this problem for a long time and after a bit of searching I figured out that this was being caused because I accidently hit Ctrl+S (Ctrl+A+S is my shortcut for switching panes), and this turns off flow control in terminals and stops the terminal from accepting input. It can be reenabled by pressing Ctrl+Q.
Source: https://superuser.com/a/553349/137226
Had a similar issue, where I had a tmux session with two buffers. I didn't see anything I typed, but when I switched between buffers what I had typed previously would appear onscreen. stty sane didn't work.
I detached Ctrl-b+d, and noticed that there was still a client attached when I looked at tmux list-clients. tmux detach-client removed it, and then I could reattach and the everything worked again.
If it is ok to lose your sessions, try deleting the tmux-NNNNNNN directory, where NNNNNNN is a number, under your /tmp directory. According to the tmux manual, if the TMPDIR environment variable is set, the tmux-NNNNNNN will be put in the TMPDIR.
tmux stores the server socket in a directory under /tmp (or TMPDIR if set);
This solved my problem of not being able to run tmux commands that are related to sessions. I also tried the following, but they did not work:
killall -9 tmux
reinstall tmux
restart shell session
I could not easily restart the operating system, because it's a shared server managed by others.
tmux was halting right after I started it. Ctrl-Q and Ctrl-C didn't do anything.
Fixed with
killall -9 tmux
(May be a different problem, but this question showed up in Google.)
I had the same issue. The cause is that the tmux buffer is full, and it also may happens cause of multi clients to the tmux session.
To solve it you need to detach all the clients from the session, and reattach it.
The best way I found to solve it is to add to the ~/.bashrc file this functions:
check_params() {
if [[ $1 < $2 ]]; then
echo -e "Usage:\n${3}"
ok=0
else
ok=1
fi
}
# detach all the clients from this session, and attach to it.
reattach_client() {
check_params $# 1 "reattach_client <tmux_session_name>"
if [[ $ok == 1 ]]; then
tmux list-client | grep $1 | awk '{split($1, s, ":"); print s[1]}' | xargs tmux detach-client -t | true
tmux attach -t $1
fi
}
then run source ~/.bashrc to make these changes in the terminal.
Now to attach the session type:
reattach_client <session_name>
solved my issue.
Thanks to Alex Zelichenko for help me with this!
You should be able to narrow down your problem a bit with a few of these tests:
Give it a shot from outside X11: Ctrl+Alt+F2 (or use ssh from another computer)
Test if other terminal emulators work: script and screen
Try another complicated terminal application: htop and mc
Reset your TTY settings: stty sane
Check that your terminal identified: echo $TERM (it should be something like "xterm" or "linux")
Make that your terminal capabilities file exists: ls -lh /usr/share/terminfo/*/$TERM
Thanks.
I found the problem. The tmux process were in D state, and I had no choice but to reboot the system.
The problem came from kerberos ticket expiring after a while. And find a scripts that solves this problem:
https://iain.cx/src/ktmux/
A less drastic action (to try before killing the tmux process) is to ssh into the machine and run the following command.
kill -CONT `pidof tmux`
Source: https://github.com/tmux/tmux/issues/507#issuecomment-271502093
This happened to me because I accidentally tried to create two parallel tmux sessions with the same name.
What worked for me was to enter htop, checking pid's of the two running commands that created the sessions, and killing both by using kill -9 pid1 and kill -9 pid2

Resources