How to know when you have a file open in vi while using the shell? - bash

When I am editting a file in vi or vim, I frequently will be editting the file, and then I need to open a shell to execute a shell command. So, I go to the shell by doing :sh.
This brings me to the shell. Now, when I want to return to the file I'm editting, I will freqquently do control + D to return the file. This works fine. I followed the instructions here.
I do a lot of work on remote AWS machines which I am ssh-d into. And, control+D is one way to exit those machines. Unfortunately, while ssh-d into those machines, sometimes I do not know if I have a file open in vi/vim and when I do control + D to go back to the file, it exits my ssh session entirely.
Is there a way to either
1) know that I have a file currently open in vi or
2) exit the shell and go back to my file safely without risking accidentally closing my ssh session?

It looks like the problem you're having isn't trying to figure out whether vi is running but rather how to jump between the parent shell and vi using "job control" (grep for job control in the bash or sh man page).
Use ctrl-z to background vi and use fg to resume. This works in all POSIX-derived shells and it works over ssh.
This is preferred over using :sh and ctrl-d since you avoid the problem you're having, you get the same shell that you were working with when you started vi, and you have one less shell running (this isn't often a performance issue but if you have a lot of shells running it's easier to look at their PIDs when needed).
There may be other reasons for :sh but the only one I know of is getting a shell in a vi session that wasn't started from a shell to begin with.
Having said that, vi -r (with no args) prints a list of swap files that subsumes the set of files open in vi. Commands like vi -r |& grep -B 3 'still running' are useful.

You can use lsof +D <dir> | grep REG
Will give you all regular files opened in your directory
For more filtering you can specify user by -u as well.

Related

-echoctl not being ackonowledged in forked program

Please,
I have a terminal application that requires no echoing of control characters back to the terminal.
I can happily issue 'stty -echoctl' at a terminal, run my application and obtain the result I am after. Further, I can include 'stty -echoctl' in .bashrc and everything is fine. (I have also added it to .profile but that seems to bring in .bashrc anyway)
I can then open another terminal (type 'konsole/gnome-terminal/xterm' in the original console and again I get the result I expect.
The problem I have (and this is in preparation of forking the program form another application) is that if i try
$ xterm -e ./V2.13
or even
$ xterm -e bash -c ./V2.13
the control characters are in fact echoed back to my app.??
EDIT:Additionally is there any need (benefit) in executing bash to execute my application ?

Preserving PS1 while in SSH with GitBash?

I have a complicated prompt. Very. I use git-bash for windows.
SSH-ing in on gitbash sends me to the CMD prompt. I know to type ssh -t user#host "bash -l" to get a bash prompt. It works, however, I use a repository called gitstatus to speed up the parsing of the git commands, and sshing in using bash -l calls the PS1 set in /c/cygwin/etc/bash.bashrc (for Mintty), NOT ~/bash.bashrc (for GitBash). This initially seems fine, as I can just copy paste the code from the GitBash *.bashrc to cygwin's. However, the gitstatus repository only works on bash terminals, aka not Cygwin/Mintty, so the prompt when I ssh in appears quite slower in git repos (Mintty doesn't allow gitstatus to be sourced and speed up parsing, once again) than if I was not SSH-ed in and using the GitBash-sourced prompt.
Are there any work arounds for this? I have seen many simnilar questions here but none have provided me a solution.
If you're in my situation, just source the scripts (duh). If you can't execute foo in file x when it should do the same thing as bar in file y, just source bar from file x. It seems obvious but took me a moment.
ALSO: Make sure to run dos2unix.exe on admin command prompt to remove carriage returns every time you make a change.

How to open a file in linux without specifiying editor?

I have emacs as my defualt editor in linux, and I also have alias in my .cshrc file.
alias e "emacs -mm"
Sometime I just want to hit the file name in the command line and open it in emacs directly with out the editor beign metioned.
Example instead of
$ e foo.cc&
What I want is to open
$foo.cc
May be this is lazy to do but it saves a lot time if you have so many files to handle. Thanks for the help.
You probably cannot open a file with $foo.cc (and that would be ambiguous for a shell script script.sh: would script.sh means "edit the file script.sh" or "run the shell script script.sh" ?). However,
You might want to use xdg-open, or the $EDITOR variable (see environ(7)). If you always have a single emacs running, you might set EDITOR to emacsclient in your ~/.bashrc (if using /bin/bash) or your ~/.zshrc (if using /bin/zsh)
BTW many editors (including emacs, gedit, vim) are able to edit several files, i.e. $EDITOR *.c
And depending upon your login shell (zsh, fish, or bash) you could set up a shell function or alias to simply type e foo.c; I feel that it is not worth the effort, since with autocompletion I just have to type 3 keys e m tab to get emacs (and often the up arrows are enough)
Actually I start only once every day emacs then open many files inside it (and also I compile inside emacs)
BTW, you should avoid csh since it is considered harmful. Install a good interactive shell (e.g. with sudo aptitude install zsh zsh-doc) and use once chsh(1) to make it your login shell.

Compact cygwin terminal

I'm looking for a way to make the cygwin terminal more compact, or an alternate terminal that is more compact. Currently, every command I enter has a header line above it with username and pwd, and there is a blank line trailing every command. For instance:
username ~
$ cd tmp
username ~/tmp
$
3 lines for every 1 line of command. I frequently work on a small screen, which makes all this wasted space quite irritating. Is there a setting somewhere I can alter to prevent all this wasted space? Or, perhaps another terminal?
Thanks in advance.
That's the default shell prompt set by Cygwin.
To use a smaller prompt in your current terminal:
PS1='$ '
To make the change permanent, put that command in your ~/.bashrc file.
You can set the prompt to just about anything you like, as explained by the bash manual (there are several variables that control different prompts; $PS1 is the main one).
It's important to remember than in Cygwin (as in Linux and Unix), the terminal program is a separate program from the shell that runs in it. The prompt is controlled by the shell; bash is the default. The graphical display is controlled by the terminal emulator, which could be rxvt, mintty, xterm, or even the Windows terminal that normally runs a DOS-like shell.
What you're seeing there is the prompt, as stored in the environment variable PS1
echo $PS1
will show you how it's created. By the way, that prompt is managed by the bash shell, not by the terminal.
export PS1=$
will give you just a $ prompt
export PS1="$ "
will leave some room behind the prompt. There are many more possibilities, here is a nice tutorial.
bash reads its settings from a file called ~/.bashrc aka a file called .bashrc in your home directory. Note that due to the initial dot in the name ls won't show the file by default, ls -a or ls -la will.
I would Recommend we go with modern terminals using Cygwin-X as shown in the below interactive menu
I love Xfce Terminal which allows creating tabs and new windows with font options and color options

After doing grep and passing it to vim then quitting, why am I experiencing this weird console malfunctioning?

I tried this just now:
grep -RlI "id=\"kw\"" * | xargs vim
That gave me 16 results. It opened the first result in Vim. I made my very first edit and hit :q since I didn't know the shortcut to jump to the next file.
It threw me back to the console ( I am SSHed in to a server ). My console is messed up now. Anything I type I can't see, and anytime I hit enter it seems like it processes the command but the display/view is screwed up so
[meder#linode] is tabbed in on my console, at least halfway. reset does nothing since it seems to have messed up my real console.
Can anyone offer a solution that doesn't have this same downside? Or can anyone provide an explanation for why :qing out of the very first file messed up my console?
Background information: My PC is Debian Ubuntu, I am SSHed into a RHEL box. The files I opened were text/ascii files phtml/php files and not some weird binary files with crazy characters in them.
Here's a screenshot of what happened
EDIT #1: I just typed reset again and it seemed to work. The first reset did not work I think because somehow the console inserted some whitespaceish character inside it? Anyways, I would like an explanation for this weird behaviour.
Try:
vim -o `grep -RlI "id=\"kw\"" * `
From the man page for xargs:
Undefined behavior may occur if utility reads from the standard input.
That line isn't in the Linux man page but it is present on my Mac. If you want to run a program that you intend to read standard input, the usual linux version of xargs will need an argument to read its input from a file:
OPTIONS
--arg-file=file, -a file
Read items from file instead of standard input.
If you use this option, stdin remains unchanged
when commands are run. Otherwise, stdin is
redirected from /dev/null.
Vim is intended to run with both standard input and standard output connected to real (a very rare case these days) or pseudo tty devices. Wierd things will happen if you upset this arrangement.
The fundamental problem with your command was that, with standard input redirected to the pipe, xargs had no way to run a vim with a "normal" standard input. So the vim mode changes and command input were not what you expected.
You can probably fix this by typing a return, a tilde, and a period. This will force your ssh session closed from your end, you can then ssh in again, and run "ps" to check for anything left hung in the background that you should kill(1).
You can use :next or :n to get to the next file to edit. You can also use vim -o to open up all the matching files in different windows in Vim.
Not sure why your console is messed up though. I tried using your command and my console was fine.
Console options are set by stty, so you may want to save its options to a bash variable and restore them after vim exits, like this:
function vim()
{
STTYOPTS="$(stty --save)"
vim "$#"
stty "${STTYOPTS}"
}
But it is probably the better way to use zsh for this task: if you put the only line ttyctl -f into your ~/.zshrc, then zsh will automatically restore terminal options after program exits. ttyctl is a zsh builtin, so you cannot use it from bash.
Other folks covered what happened and what to do about it. As to why, the answer to that probably lies in what input Vim received from the xargs command and tried to execute as if that input came from a terminal. I don't know how to talk terminal, but you can imagine that Vim got some strange commands that crashed it or told it to quit. Similarly unpredictable things happen when you cat a binary file.
Anway, I have another idea. Have you tried using vimgrep to browse a list of files matching a pattern?
:vimgrep /id="kw"/ *
:copen
This greps for id="kw" in all files in the current directory. :copen opens up a window with a list of matches. You can browse that list, clicking enter to jump to a file position.
For more information, see
:help grep
:help :vimgrep
:help :copen
:help quickfix
If you really need that -I option, see
:help :grep
:help 'grepprg'
See also: Vim: Warning: Input is not from a terminal
Try to use ... | xargs sh -c '...' and then read from the controlling terminal device /dev/tty.
echo ~/.profile ~/.bashrc | xargs sh -c 'vim "$#" </dev/tty' dummy_script_name
# based on a tip by Laszlo Ersek on http://unix.derkeiler.com/Newsgroups/comp.unix.programmer/2010-03/msg00051.html
#find . -maxdepth 1 -type f | xargs sh -c 'rm -i "$#" </dev/tty' dummy_script_name

Resources