Bash provides the feature of colors for specific types of files. For example, by default ls will show directories as blue, utilities as green, files as white and etc. I know these colors can be customized for the output of commands such as ls via modifying ~/.dir_colors and other files depending upon how widespread on the system the change should be applied.
However, during screen-casts and presentations I have seen the command line itself have these color modifications. For example at the bash prompt if someone types a utility and starts typing its arguments, the utility on the line is colored green as it would be in the output of ls. This seems like a nice feature, but all google searches seem to turn up is how to modify outputs of ls and customize the colors, but not how to apply this to the command line itself. How can this be applied to the command line? Is it possible via bash or is this a feature of some terminal software these users are using?
fish - the Friendly interactive shell https://en.wikipedia.org/wiki/Friendly_interactive_shell looks like it reacts as you describe.
Not sure how helpful it will be but the tput command can help with changing the colours and formatting of the command line.
For example, to change the colour of the text in your terminal to red you can do.
tput setaf 1
This accepts numerical arguments between 1 and 7. This could then be added to ~/.bash_profile or ~/.bashrc in order to set the colours at the time of user login or when a new terminal session is started.
Along with changing colours tput has the ability to make the text bold, underlined and more.
For more usage check out these pages:
TDLP - http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x405.html
Hack40- http://linux.101hacks.com/ps1-examples/prompt-color-using-tput/
Oh yeah, I always do this for every Mac and Linux server I have. Not only can you tell it to provide useful info such as "user#server-name: working/directory", but it's just plain fun!
I like to have mine tell me which Git branch I'm working on, when I'm inside a Git repository!
You just have to add one change to your ~/.bash_profile or ~/.bash_rc
Here is a website the will help you generate the complicated code: https://www.kirsle.net/wizards/ps1.html
And just so you have an example, here is what I use on my personal Mac (without the Git branch detection):
PS1='\[\033[02;36m\][\u#MBP:\[\033[02;33m\]\w]\$\[\033[00m\] '
The above code will give you:
A teal color showing your user and a static hostname: "user#MBP". You can rename the hostname to anything you like.
Then, a yellow 'current working directory'
Lastly followed by a '$' symbol and resets the colors back to white
Specifying the colors for different parts gets tricky. I'd definitely recommend using the generator. But if you want to blaze your own trail, here is a list of all the codes for the bash colors: http://blog.bigdinosaur.org/easy-ps1-colors/
To have it set every time you login to your workstation add above export command to your $HOME/.bash_profile file or $HOME/.bashrc file.
vi $HOME/.bashrc
Append the following lines:
export PS1="\[\e[31m\][\[\e[m\]\[\e[38;5;172m\]\u\[\e[m\]#\[\e[38;5;153m\]\h\[\e[m\] \[\e[38;5;214m\]\W\[\e[m\]\[\e[31m\]]\[\e[m\]\\$ "
cat<<'EOF'
_..._
.' '.
/ _ _ \
| (o)_(o) |
\( ) /
//'._.'\ \
// . \ \
|| . \ \
|\ : / |
\ `) ' (` /_
_)``".____,.'"` (_
) )'--'( (
'---` `---`
EOF
Save and close the file in vim/vi.
To get into the ex mode, press [Esc] key and then : (the colon). For example, to exit from vi saving changes, press [Esc], : (colon) and type wq:
:wq
You can also quit, discard all changes by pressing [Esc], : (colon) and q!.
:q!
You need to press [Esc] key followed by the colon (:) before typing the following commands:
| Command | Description |
|------------- |---------------------------------------------------------------- |
| q | Quit |
| q! | Quit without saving changes i.e. discard changes and quit file |
| r fileName | Read data from file called fileName |
| w | Save file and continue editing |
| wq | Write and quit (save and exit) |
| x | Same as wq command i.e. write and quit (save and exit) |
| w fileName | Write to file called fileName (save as) |
| w! fileName | Overwrite to file called fileName (save as forcefully) |
Related
Is it possible to have a bash script split the terminal window horizontally at one point, so that the left side details the overall progress of tasks, and the right side contains verbose output from the current task being run?
I've found some people referencing nohup and screen in contexts of splitting the terminal window, but I don't know how to get that going in a bash script sense, or if its even the right direction for my needs.
At the moment, I've got lots of long tasks with long output, so I'm sending the output of each to a cumulative log file, instead of dumping on the screen. Then, as an interim, manually opening a new terminal window to use watch tail LogFile* to keep an eye on what's going on.
It would be great if I could automate that process.
Update
Some leads.
This post and its comments were very helpful, to establish that you can launch a command in one window and send its output to another based on its pts value.
For example, ls > /dev/pts/7 will display output of ls in the terminal window at pts/7.
Still stumped about how to automate splitting the screen programatically, and using that, instead of a new window.
I got a working example going with Terminator.
Start the bash script below in a new Terminator window:
terminator --command="bash /path/to/script"
And once we're running in that, it's a bit of a hack solution, but to split the screen by command-line in the bash script, I ended up using xdotool to send keybindings to Terminator. Like so:
#!/bin/bash
# send keybinding that splits screen vertically
xdotool key Ctrl+Shift+E
# Terminator now sets focus to the right side (the new split) by default, so send keybinding that returns the focus to our left side
# sleep a tiny little bit first
sleep 0.01
xdotool key Alt+Left
# now to send output to the right side, let's work out "where" the ride side is
# use who to find the pts ids of all currently spanwed terminal windows
# use tail to find the last line from who (which we assume is the terminal window we just split)
# then grep to find just the number after pts/
## windowID=$(who | tail -n1 | grep -oP 'pts/\K[0-9]*')
# updated this to fix bug where who does not return pts values
# https://askubuntu.com/questions/1110203
windowID=$(ps -u $USER -o tty | awk 'NR>1 && $1 != "?" {a[$0]++};END{for(val in a) print val}' | tail -n1 | grep -oP 'pts/\K[0-9]*')
# now we can send output from commands to the right side split window by using its pseudo device id. for example:
ls -lah >> /dev/pts/$windowID
exit
I created a function clip that copies the output of the last command to clipboard by rerunning it first.
#copy previous output to clipboard
function clip(){
echo $(!!) | pbcopy
}
When I run the individual line contained in the function in my terminal it works perfectly. However, if I try to save it as a function in my .zshrc and execute it by calling clip, I get the following error:
zsh: command not found: !!
I can't get the automatic expansion to work properly, any help would be appreciated.
clip () {
fc -ILe- | pbcopy
}
Explanation:
History expansion with !! only works if it is typed into an interactive commandline. It will not work from within a script as !! is not handled in a special way there (leading to the "command not found" error).
Instead you can use the fc command to retrieve elements from the history.
Running fc without any parameters will retrieve the last history event and open an editor with the event in it for editing. Closing the editor will then run the edited command (not saving an edit will lead to the original command to be executed).
The parameters from the above example will modify the behavior as follows:
-I: Only retrieve internal history events, that is, exclude events loaded from $HISTFILE.
-L: Only retrieve local history events, excluding elements shared form other sessions via SHARE_HISTORY. (This may not be necessary in combination with -I, but I did not test this)
-e ename: use ename as editor instead of the default editor. if ename is set to -, then no editor is opened.
-I and -L are not strictly necessary, but they prevent you from inadvertently running which ever command was typed in last in some previous shell session. This could very well have been rm -r * or poweroff.
So in combination fc -ILe- | pbcopy will retrieve the last command entered into the current shell session and pipe its output to pbcopy.
BTW: You can just use cmd1 | cmd2 instead of echo $(cmd1) | cmd2 in order to be able to pipe the output of cmd1 to cmd2.
I'm writing a small program that prints to the terminal its output in tab separated format. But whenever I select the text with tabs and copy it, the tabs are replaces with some number of spaces.
What can I do to make terminal not replace tabs with spaces when trying to copy?
On macOS Sierra (maybe also in earlier versions), you can do:
Edit -> Copy Special -> Copy Plain Text
Or using the shortcut:
alt+shift+⌘ cmd+C
Your best bet may be to substitute "\t" in place of tabs in your output, and do a search and replace after you copy and paste it to the destination.
You could use any character or string as the substitute, of course, but using "\t" makes it easy to restore the tabs using echo -e if pasting to a command-line environment.
The substitution can be done using: |sed 's/\\/\\\\\\/g;s/\t/\\t/g'
I am able to do it on my mac terminal. Here are some good tests:
printf '>\t<\n' : works (copies into sublime as a tab; selecting it only lets me select the full tab not individual spaces)
printf '>\t<\n' | less : fails
printf '>\t<\n' | more : fails
printf '>\t<\n' | less | cat : works (less detects output is file/pipe not terminal so no terminal settings applied)
printf '>\t<\n' | less | cat -vet : outputs ">^I<$" (less detects pipe output so no terminal settings applied)
printf '>\t<\n' | vi - : fails but when I move in vi, it jumps across the tab in 1 keypress so it knows it is a tab
reset : from now on, it always fails
stty -tabs : from now on, it always fails
stty tabs : fixes the reset/stty -tabs problem, now it can work again
One guy got less to work by altering the source: https://unix.stackexchange.com/questions/412060/how-to-get-less-to-show-tabs-as-tabs
less related options: '-U' shows tabs as '^I', '-x4' sets tab size
For git diff:
git diff | head -40 : works (copies into sublime with tabs)
git diff | cat : works
git diff | less : fails (less applies terminal settings)
git diff : fails (my git pager is less)
So I am on an old (fully aluminum) macbook pro running snow leopard and using terminal to ssh into remote hosts on my work network. I am noticing a strange thing when I copy and paste things in the terminal.
For example I will grep for something like this in a file:
samtools view sorted-616.bam | grep 'SOLEXA9:1:1:30:3316:10211' | head -n 1
and it gives
SOLEXA9:1:1:30:3316:10211 69 k26_179705 159 0 * = 159 0 TATGCCGCCAAACGCTTCCGCAAAGCTCTGTGTTTGACTATGTAGCGACTA CBCCCCCC#CCCCCCCCC?#CC?CC########################## RG:Z:1
But now when I select it, hit command+c to copy, and then command+v to paste, it comes out like this:
SOLEXA9:1:1:30:3316:1021169k26_1797051590*=1590TATGCCGCCAAACGCTTCCGCAAAGCTCTGTGTTTGACTATGTAGCGACTACBCCCCCC#CCCCCCCCC?#CC?CC##########################RG:Z:1
Notice how there are no spaces in between fields now. Is there a special method to copy and paste things exactly as they are?? Why is terminal behaving this way?
What happens when you use pbcopy?
samtools view sorted-616.bam | grep 'SOLEXA9:1:1:30:3316:10211' | head -n 1 | pbcopy
This should do the same thing that the copy command does, but without having to select the output you want.
Have you tried another terminal emulator? I use iTerm2 because it will copy to the clipboard on selection without having to hit Command-c.
EDIT: You may have to install Apple's developer tools to get the pbcopy/pbpaste tools.
No idea why the spaces are missing from the pasted text, but I'd try to write the output to a file, open up the file in an editor and try to see if it's something other than the standard space/newline characters. You seem to know your way with piping, but anyway:
samtools view sorted-616.bam | grep 'SOLEXA9:1:1:30:3316:10211' | head -n 1 > file.txt
It might depend on which system the host is running. I have had some issues while on ssh connections to linux/unix hosts, while Mac-to-Mac usually works just fine.
I use Alt-! (Alt-Bang) a lot in Emacs. One of the big things I use it for is
Alt-! cat $logfile | grep 'this' # show me one kind of event
or sometimes
Alt-! cat $logfile | grep 'this' | wc -l # count that one event's occurrences
Two things:
1) No tab-completion from this prompt: why not?
2) What if instead of $logfile, I want to scan one of the Emacs buffers?
To scan an Emacs buffer, use M-| instead of M-!: it passes the region as input to the command. Use M-1 M-| if you want the output of the command to replace the region.
For the particular command you mention, use M-x grep if you want to see all matches. Or you can open it and see the matches with M-x occur.
Alt-| does is shell-command-on-region
with a(ny) numeric prefix (e.g. C-u 1 Alt-|) the region is replaced by the result, otherwise that appears in new buffer