dtalk shell
DESCRIPTION
Bash & zsh tips and tricks. Two dozen of (un)useful one-liners.TRANSCRIPT
Console Tips&Tricks
Two dozen (un)useful one-
liners
Me, Myself and I.
❖ Ex (win) sysadmin, ex (lousy) php dev
❖ Rails developer @dlabs, still a bit lousy, getting better
❖ @miha_mencin, radiokills@github
Its all about history
$ history
…
7550 git commit -a -m 'renaming pg to postgresql in database.yml template'
7551 git push origin master
7552 git push origin postgres
7553 rake update web web1 testing
7554 bundle
7555 rake update web web1 testing
7556 bundle update
7557 rake update web web1 testing
…
$ cat ~/.zsh_history
…
: 1378713558:0;diff
: 1378713783:0;git commit -a -m 'duplicated_payment_details'
: 1378713798:0;git push origin duplicated_payment_details:
: 1378713805:0;git push origin duplicated_payment_details
: 1378716721:0;git checkout -b alter_service_center_payment
: 1378716812:0;rails g migration add_bank_details_to_service_center bank_account bank_sorting_code
: 1378719452:0;git commit -a -m 'migration, validation, form, DIP-257'
: 1378720670:0;git merge diplicated_payment_detail
…
Controll your history
$ echo $HISTSIZE
1000
$ echo $HISTFILESIZE
2000
$ echo $HISTFILE/home/miha/.zsh_history
$ vi ~/.zshrc
…
export HISTSIZE=10000
export HISTFILESIZE=2000
export HISTIGNORE=cd:cat:dir
…
Command line pr0n mode? Yes we can!
$ <space>vi love-letter-to-my-mistress.txt
Use your history
[CTRL] + r = (fuzzy) search through history
$ vi ~/.ssh/known_hosts
bc-i-search: vi
$ history
…
7550 git commit -a -m 'renaming pg to postgresql in database.yml template'
7551 git push origin master
7552 git push origin postgres
7553 rake update web web1 testing
7554 bundle
7555 rake update web web1 testing
7556 bundle update
7557 rake update web web1 testing
…
$ !7556
Fetching gem metadata from https://rubygems.org/...
➜ !7556
➜ bundle update
Fetching gem metadata from https://rubygems.org/...
Re-run last command
$ ls -lahdrwxrwxr-x 3 miha miha 4.0K Jul 26 18:52 apps
-rw------- 1 miha miha 649 Jul 26 21:58 .bash_history
-rw-r--r-- 1 miha miha 220 Jul 26 12:26 .bash_logout
-rw-rw-r-- 1 miha miha 200 Jul 26 12:53 .bash_profile
-rw-r--r-- 1 miha miha 3.7K Jul 26 12:53 .bashrc
drwx------ 2 miha miha 4.0K Jul 26 12:31 .cache
drwxrwxr-x 3 miha miha 4.0K Jul 26 15:05 .gem
-rw------- 1 miha miha 41 Oct 18 09:55 .mysql_history
drwxrwxr-x 10 miha miha 4.0K Jul 26 22:03 .oh-my-zsh
…
$ fc -ln -1
ls -lah…
$ $(fc -ln -1)drwxrwxr-x 3 miha miha 4.0K Jul 26 18:52 apps
-rw------- 1 miha miha 649 Jul 26 21:58 .bash_history
-rw-r--r-- 1 miha miha 220 Jul 26 12:26 .bash_logout
-rw-rw-r-- 1 miha miha 200 Jul 26 12:53 .bash_profile
-rw-r--r-- 1 miha miha 3.7K Jul 26 12:53 .bashrc
sudo Re-run last command
$ nginx -s reloadnginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
2014/10/19 12:09:52 [warn] 1800#0: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:1
2014/10/19 12:09:52 [notice] 1800#0: signal process started
2014/10/19 12:09:52 [alert] 1800#0: kill(1007, 1) failed (1: Operation not permitted)
…
$ sudo nginx -s reload
$ sudo $(fc -ln -1)
$ sudo !!
“!!” is called ‘expansion’. !22124 is also expansion.
More about expansions
$ !!
Repeats last command
$ !2123
Repeats command 2123 from history
$ !$
Expands to last argument. For example:
$ mkdir -p /home/miha/awesome_folder/awesome_subfolder/data
$ cd !$
$ pwd
/home/miha/awesome_folder/awesome_subfolder/data
$
(Similar thing can be achieved by pressing [Esc] and then [.]
$ cd ~
We all know it
Even more expansions$ A=ruby
$ echo $A
ruby
$ A=ruby
$ echo ${#A}
4
$ A=ruby
$ echo ${A/r/ch}
chuby
$ echo ${A^}
Ruby
$ echo ${A^^}
RUBY
//use ${A,,} for downcast
Brace expansions$ echo {1,2,3}
1 2 3
$ echo file-{a,b,c}
file-a file-b file-c
$ echo {1..5}
1 2 3 4 5
$ echo {2..-3}
2 1 0 -1 -2 -3
$ echo {a..e}
a b c d e // does not work in zsh
➜ setopt BRACE_CCL
➜ echo {a-e}
a b c d e
Brace expansions
$ rm !(*.rb|*.py)
$ lsfilea1.py filea2.rb filea4.py fileb1.rb ……..
$ mv fileb1.{py,cpp}
$ cp fileb2.{py,bak}
$ touch file{a..d}{1..4}.{rb,py,css,js}
$ ls
filea1.css filea2.py filea4.css fileb1.py fileb3.css fileb4.py filec2.css filec3.py filed1.css filed2.py filed4.css
filea1.js filea2.rb filea4.js fileb1.rb fileb3.js fileb4.rb filec2.js filec3.rb filed1.js filed2.rb filed4.js
filea1.py filea3.css filea4.py fileb2.css fileb3.py filec1.css filec2.py filec4.css filed1.py filed3.css filed4.py
filea1.rb filea3.js filea4.rb fileb2.js fileb3.rb filec1.js filec2.rb filec4.js filed1.rb filed3.js filed4.rb
filea2.css filea3.py fileb1.css fileb2.py fileb4.css filec1.py filec3.css filec4.py filed2.css filed3.py
filea2.js filea3.rb fileb1.js fileb2.rb fileb4.js filec1.rb filec3.js filec4.rb filed2.js filed3.rb
file.1.rb file.2.rb file.3.rb file.4.rb filea1.rb filea2.rb filea3.rb filea4.rb filed1.rb filed2.rb filed3.rb filed4.rb
Pipes
About pipes
$ ls -l | grep filea1-rw-r--r-- 1 miha staff 0 Oct 21 22:19 filea1.py
-rw-r--r-- 1 miha staff 0 Oct 21 22:19 filea1.rb
$ ls -l | grep filea1 > myfiles.txt
$ cat mayflies.txt-rw-r--r-- 1 miha staff 0 Oct 21 22:19 filea1.py
-rw-r--r-- 1 miha staff 0 Oct 21 22:19 filea1.rb
Pipes let you use the output of a program as the input of another one
Redirection makes it possible to control where the output of a command goes to,
and where the input of a command comes from. (via bash-hackers.org)
Useful piping
local1$ ssh our-db-serv.net
dbserv$ mysqldump my_remote_db > my_remote_db.sql
local1$ scp our-db-serv.net:/path/to/my_remote_db.sql .
local1$ mysql my_local_db < my_remote_db.sql
$ ssh our-db-serv.net 'mysqldump my_remote_db' > my_remote_db.sql
$ mysql my_local_db < my_remote_db.sql
Task: Copy a mysql database over the ssh
But… It is so much work… And I need coffee
Still… can we do better? Yes we can!
$ ssh our-db-serv.net 'mysqldump my_remote_db' | mysql my_local_db
Not everyone’s happy
Umm, yeah…. If you’d just make it - let’s say - twice as fast…
That’d be great
Yes we can!!
But… we really (almost) can.
$ ssh our-db-serv.net 'mysqldump my_remote_db | gzip -c' | gunzip | mysql my_local_db
But… Is it happening at all?
$ ssh our-db-serv.net 'mysqldump my_remote_db | gzip -c' | pv | gunzip | mysql my_local_db
6MiB 0:00:13 [2.35MiB/s] [ <=> ]
How much coffee can I have in meantime?
$ ssh …| pv -s 200m | gunzip | mysql my_local_db
35.9MiB 0:00:15 [2.34MiB/s] [========> ] 17% ETA 0:01:08
That is not enough time for coffee break :(
$ ssh …| pv -s 200m -L128K | gunzip | mysql my_local_db
5.38MiB 0:00:43 [ 125kiB/s] [> ] 2% ETA 0:25:57
(In some cases we could use tee)
$ ls | tee files.txt
Piping through ruby
$ echo "My String" | ruby -e "puts gets.downcase”
> my string
# upcase.rb
ARGF.each do |line|
puts line.upcase
end
$ ls | ruby upcase.rbFILE1.TXT
FILE2.TXT
FILE3.TXT
FILE4.TXT
UPCASE.RB
Aliases
$ alias
…
l='ls -lah'
la='ls -lAh'
ll='ls -lh'
ls='ls -G'
lsa='ls -lah'
md='mkdir -p
…
A Bash alias is essentially nothing more than a keyboard shortcut, an abbreviation,
a means of avoiding typing a long command sequence
Alias scopes
$ sudo ll
sudo: ll: command not found
$ alias sudo=‘sudo ‘
$ sudo ll-rw-r--r-- 1 miha staff 0B Oct 22 00:30 file1.txt
-rw-r--r-- 1 miha staff 0B Oct 22 00:30 file2.txt
-rw-r--r-- 1 miha staff 0B Oct 22 00:30 file3.txt
zsh specific aliases
Zsh specific aliases
-s (suffix aliases)
$ alias -s rb=subl
$ somefile.rb
# will open somefile.rb in sublime text
# we can set multiple filetypes also
$ alias -s {mkv,avi}=vlc
-g (gloabal aliases)
$ alias -g G=“| grep -i”
$ ls G filefile1.txt
file2.txt
file3.txt
file4.txt
Let’s have some fun
$ nginx -s reloadnginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
2014/10/22 01:08:01 [warn] 2282#0: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:1
2014/10/22 01:08:01 [notice] 2282#0: signal process started
2014/10/22 01:08:01 [alert] 2282#0: kill(1038, 1) failed (1: Operation not permitted)
$ alias please='$(fc -ln -1)'
$ nginx -s reload
#error msg..
$ sudo please
$ #yeey
But… also…
$ alias bitch=‘sudo ‘
Let’s have some fun
$ nginx -s reloadnginx: [alert] could not open error log file: open() "/var/log/nginx/error.log" failed (13: Permission denied)
2014/10/22 01:08:01 [warn] 2282#0: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:1
2014/10/22 01:08:01 [notice] 2282#0: signal process started
2014/10/22 01:08:01 [alert] 2282#0: kill(1038, 1) failed (1: Operation not permitted)
More of zsh awesomeness
Tab completion I
Tab completion II
$ cd /u/l/b # +[TAB] =
$ cd /usr/local/bin
$ git # +[TAB] =add -- add file contents to index
am -- apply patches from a mailbox
apply -- apply patch to files and/or to index
archimport -- import an Arch repository into git
archive -- create archive of files from named tree
bisect -- find, by binary search, change that introduced a bug
blame -- show what revision and author last modified each line of a file
branch -- list, create, or delete branches
bundle -- move objects and refs by archive
cat-file -- provide content or type information for repository objects
Tab completion III
More of zsh awesomeness
cd between subfolders
$ cd /home/miha/projects/dipstix/app/assets/javascripts
# Upsie, wrong project
$ cd dipstix playon
$ pwd
/home/miha/projects/playon/app/assets/javascripts
$ spec
zsh: correct 'spec' to 'rspec' [nyae]?
$ unsetoption correct_all
Autocorrection - can be annoying
Recursive listing
$ ls **/action_card*-rw-r--r-- 1 miha staff 530B Jul 31 14:48 app/admin/action_card_priorities.rb
-rw-r--r-- 1 miha staff 1.8K Sep 30 12:07 app/admin/action_cards.rb
-rw-r--r-- 1 miha staff 1.5K Aug 13 10:00 app/controllers/api/v1/action_cards_controller.rb
-rw-r--r-- 1 miha staff 1.2K Aug 20 15:01 app/models/action_card.rb
More of zsh awesomeness
Edit your variables
$ vared PATH
/Users/miha/.rvm/gems/ruby-2.1.1@firely-api/bin:/Users/miha/.rvm/gems/ruby-2.1.1@global/bin:/Users/miha/.rvm/rubies/ruby-
2.1.1/bin:/Users/miha/.rvm/bin:/usr/local/heroku/bin:/usr/local/texlive/2014basic/bin/x86_64-
darwin:/usr/local/bin:/usr/local/sbin:/Users/miha/.bin:/Applications/Postgres.app/Contents/Versions/9.3/bin:/usr/local/bin:/usr/local/sbin:/
usr/bin:/bin:/usr/sbin:/sbin:/Applications/Postgres.app/Contents/Versions/9.3/bin:/bin
oh-my-zsh
oh-my-zsh is an open source, community-driven framework
for managing your Zsh configuration.
It comes bundled with a ton of helpful functions,
helpers, plugins, themes, and a few things that make you shout…
$ curl -L http://install.ohmyz.sh | sh
oh-my-useful-aliases
..='cd ..'
...='cd ../..'
1='cd -'
2='cd -2’
…
d='dirs -v | head -10’
$ d0 ~/www_rails/playon/lib/tasks
1 ~/www_rails/playon/lib
2 ~/www_rails/playon
3 ~/www_rails
4 ~/www_rails/dipstix/app
5 ~/www_rails/dipstix/app/controllers
6 ~/www_rails/dipstix/app/controllers/custom_devise
7 ~/www_rails/dipstix
8 ~/www_rails/dipstix/lib
9 ~
$ 3
~/www_rails
To sum up…
$ history | awk '{print $2}' | sort | uniq -c | sort -nr | head
2807 git
920 cd
454 ssh
382 ls
375 rails
348 ll
343 l
341 rake
291 sudo
165 rm
thnx and…
to work with us