\documentclass{beamer} \usepackage{lmodern} \usepackage[czech]{babel} \usepackage[utf8x]{inputenc} \usepackage[T1]{fontenc} \usepackage{textpos} \usepackage{tikz,calc} \usepackage{graphicx} \usepackage{wrapfig} \usepackage{color} \usepackage{mathtools} \usepackage{hyperref} \usepackage{epstopdf} \usepackage{amsmath} \usepackage{minted} \hypersetup{ colorlinks, citecolor=black, filecolor=black, linkcolor=black, urlcolor=black } \usepackage{pdflscape} \input{theme/theme.tex} \title{Tipy a triky nejenom v shellu nejenom pro programátory} \author{Karel Kočí} \date{8.10.2017} \AtBeginSection[]{ \begin{frame} \tableofcontents[currentsection] \end{frame} } \begin{document} \input{theme/title.tex} \begin{frame}[fragile]{O čem to bude?} \begin{minted}[frame=lines]{shell} sed 's/[^\;]*\;//' hist | tr ' ' '\n' | \ grep -vE '^(-|\||$)' | sort | uniq -c | \ sort -nr > notes/tatnppvl.result \end{minted} \begin{tabular}{r|l|r|l|r|l} \hline 3004 & ls & 2391 & cd & 2225 & git \\ \hline 1350 & v & 911 & sudo & 608 & tig \\ \hline 458 & emerge & 410 & push & 405 & ssh \\ \hline 393 & .. & 381 & gst & 372 & ci \\ \hline 320 & add & 303 & vim & 285 & make \\ \hline 285 & grep & 282 & rm & 247 & man \\ \hline 203 & . & 191 & co & 189 & sed \\ \hline 172 & @world & 159 & ./build\_repo.sh & 156 & omnia \\ \hline 150 & updater & 148 & mpv & 140 & turris/openwrt \\ \hline 138 & mount & 124 & cp & 120 & test \\ \hline 119 & pull & 112 & ip & 109 & turtetris/Makefile \\ \hline \end{tabular} \end{frame} \section[Section]{Jen shell} \begin{frame}[fragile]{MAN MAN MAN MAN MAN} \begin{minted}[frame=lines]{shell} man man man exit man 3 exit \end{minted} Z man man: \begin{enumerate} \item Spustitelný program nebo shell příkaz \item Volání systému (funkce z kernelu) \item Knihovní volání (funkce poskytované knihovnami) \item Speciální soubory (obvykle soubory z /dev) \item Souborové formáty a konvence (například /etc/passwd) \item Hry \item Různorodé (Konvence, makra a pod.) \item Příkazy pro systémovou administraci (obvykle sbin) \end{enumerate} \end{frame} \begin{frame}[fragile]{Náhled na soubory} \begin{block}{ll} Pro přístupová práva, vlastníky i velikost. \begin{minted}[frame=lines]{shell} alias ll='ls -lh' \end{minted} \end{block} \begin{block}{tree} Pro stromovou strukturu. \end{block} \end{frame} \begin{frame}[fragile]{Připisované soubory} \begin{block}{tail -f} \begin{minted}[frame=lines]{shell} sudo tail -f /var/log/messages \end{minted} \end{block} \end{frame} \begin{frame}[fragile]{Opakované spuštění} \begin{block}{while true; do sleep 1; \emph{command}; done} Pro sledování a pod. Například ip address. \end{block} \begin{block}{dorepeat} \begin{minted}[frame=lines]{shell} dorepeat() { while true; do "$@" sleep 1 echo done } \end{minted} \end{block} \end{frame} \begin{frame}[fragile]{Hledání souborů} \begin{block}{find -name -delete} \begin{minted}[frame=lines]{shell} find -name *elf* find -name *.orig -delete \end{minted} \end{block} \end{frame} \begin{frame}[fragile]{Hledání souborů podle obsahu} \begin{block}{grep -Rn PATTERN} \begin{minted}[frame=lines]{shell} grep -Rn elfutils grep -RnE 'elf-?utils' \end{minted} \end{block} \end{frame} \begin{frame}[fragile]{Hledání podle obsahu ve specifických souborech} \begin{minted}[frame=lines]{shell} find -name Makefile | xargs grep -Rn elfutils \end{minted} \end{frame} \begin{frame}[fragile]{Náhodné heslo} \begin{block}{genpasswd} \begin{minted}[frame=lines]{shell} genpasswd() { local l=$1 [ -n "$l" ] || l=16 tr -dc A-Za-z0-9_ < /dev/urandom \ | head -c "$l" | xargs } \end{minted} \end{block} \end{frame} \section[Section]{X server} \begin{frame}[fragile]{Clipboard} \begin{block}{xclip -selection clipboard} \begin{minted}[frame=lines]{shell} cat .ssh/id_rsa.pub | xclip -selection clipboard \end{minted} \end{block} \begin{block}{clip} \begin{minted}[frame=lines]{shell} clip() { # Note: printf is magic to remove trailing new lines printf %s "$(cat)" | xclip -selection clipboard } \end{minted} \end{block} \end{frame} \begin{frame}[fragile]{Screenshot} \begin{block}{xshot} \begin{minted}[frame=lines]{shell} xshot() { import -window "$(xdotool selectwindow)" \ ~/xshot_$(date +%F_%H%M%S_%N).png } \end{minted} \end{block} \end{frame} \section[Section]{Git} \begin{frame}[fragile]{Git aliases} \begin{block}{git co ci br wt} \textasciitilde/.gitconfig \begin{minted}[frame=lines]{ini} [alias] co = checkout ci = commit st = status br = branch wt = worktree \end{minted} \end{block} \begin{block}{gst} \begin{minted}[frame=lines]{shell} alias gst='git status' \end{minted} \end{block} \end{frame} \begin{frame}[fragile]{Verbose commits} \textasciitilde/.gitconfig \begin{minted}[frame=lines]{ini} [commit] verbose = true \end{minted} \begin{verbatim} # Changes to be committed: # modified: utils/localrepo # ------------------------ >8 ------------------------ diff --git a/utils/localrepo b/utils/localrepo HELP_DESCRIPTION = """ - Local opkg repository management script. + Local opkg repository management tool. """ \end{verbatim} \end{frame} \begin{frame}[fragile]{git worktree} \begin{block}{git worktree add} \begin{minted}[frame=lines]{shell} git branch work-todo git worktree add ../project-work-todo work-todo \end{minted} \end{block} \begin{block}{git worktree prune} \begin{minted}[frame=lines]{shell} rm -rf ../project-work-done git worktree prune \end{minted} \end{block} \end{frame} \begin{frame}[fragile]{Git hash $\to$ clipboard} \begin{block}{gitclip} \begin{minted}[frame=lines]{shell} gitclip() { [ -n "$1" ] && local CMT="$1" || local CMT=HEAD git rev-parse "$CMT"| clip } \end{minted} \end{block} \begin{block}{gitmclip} \begin{minted}[frame=lines]{shell} gitmclip() { [ -n "$1" ] && local CMT="$1" || local CMT=HEAD git log --format=%B -n 1 "$CMT" | clip } \end{minted} \end{block} \end{frame} \begin{frame}[fragile]{gitbmerge} \begin{minted}[frame=lines]{shell} gitbmerge() { ( set -e local WT="$(git worktree list \ | sed -nE "/\[$1\]/{s/([^ ]+) .*/\1/p}")" if [ -n "$WT" ]; then rm -r "$WT" git worktree prune fi git merge --ff-only "$1" && \ git push && git branch -d "$1" \ && git push origin :"$1" ) } \end{minted} \end{frame} \section[Section]{Stahování} \begin{frame}[fragile]{Zpracování obsahu pomocí shellu} \begin{block}{curl HREF | tar -xzf -} \begin{minted}[frame=lines]{shell} curl http://repo.turris.cz/turris/OpenWrt-SDK.tar.bz2 \ | tar -xzf - \end{minted} \end{block} \begin{block}{curl -s HREF | grep -n} \begin{minted}[frame=lines]{shell} curl -s http://repo.turris.cz/turris/lists/base.lua \ | grep -n updater-ng \end{minted} \end{block} Nikdy! \begin{verbatim}curl HREF | sh -s\end{verbatim} \end{frame} \begin{frame}[fragile]{Stažení všeho ze serveru} \begin{block}{wget -r --no-parent (-l1)} \begin{minted}[frame=lines]{shell} wget -r --no-parent \ http://repo.turris.cz/turris/packages/ \end{minted} \end{block} \end{frame} \section[Section]{SSH} \begin{frame}[fragile]{Spuštění příkazu na několika hostech} \begin{minted}[frame=lines]{shell} ROUTERS="1 159 189 156 104 199 135 171 244 172" I=0 for R in $ROUTERS; do echo "=== Runnining on 192.168.1.$R ===" ssh -i ~/router root@192.168.1.$R -- $@ #scp -i ~/router user.lua \ # root@192.168.1.$R:/etc/updater/user.lua #ssh -i ~/router root@192.168.1.$R \ # -- uci set turtetris.line=$I #I=$(expr $I + 1) done \end{minted} \end{frame} \begin{frame}[fragile]{Port forward} \begin{minted}[frame=lines]{shell} ssh host -L 8484:localhost:8384 \end{minted} \end{frame} \begin{frame}[fragile]{SOCKS proxy} \begin{minted}[frame=lines]{shell} ssh host -D 8123 \end{minted} \end{frame} \begin{frame}[fragile]{Trvalé připojení} \begin{block}{cmd} \begin{minted}[frame=lines]{shell} ssh host -o ControlMaster=auto \ -o ControlPath=$MCNF_DIR/.ssh_access/%r@%h:%p \ -o ControlPersist=600 \end{minted} \end{block} \begin{block}{ssh config} \begin{minted}[frame=lines]{shell} Host * ControlMaster auto ControlPath .cache/ssh/%r@%h:%p ControlPersist 600 \end{minted} \end{block} \end{frame} \section[Section]{Bash (Zsh) a emulátor terminálu} \begin{frame}[fragile]{Prompt a exit code} \begin{minted}[frame=lines]{shell} PROMPT_COMMAND=' EC=$? if [[ $EC < 0 ]]; then echo -e "\e[1;31m"EXIT: $EC"\e[0m" elif [[ $EC > 0 ]]; then echo -e "\e[1;33m"EXIT: $EC"\e[0m" fi' \end{minted} \end{frame} \begin{frame}[fragile]{Xterm (urxvt) title} \begin{minted}[frame=lines]{shell} function settitle { echo -ne "\033]0;`whoami`@`hostname`:`pwd`\007" } case "$TERM" in xterm*|*rxvt*) trap 'settitle' DEBUG ;; esac \end{minted} \end{frame} \begin{frame}[fragile]{Zsh upozornění od dlouho-běžícího procesu} \tiny \begin{minted}[frame=lines]{shell} lrbell_duration=15 lrbell_timestamp=$EPOCHSECONDS lrbell_window_id=0x0 lrbell_active_window_id() { xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2 } lrbell_begin() { lrbell_timestamp=$EPOCHSECONDS lrbell_message="`pwd`: $1" if [ -n "$DISPLAY" ]; then lrbell_window_id=$(lrbell_active_window_id) fi } lrbell_end() { (( $EPOCHSECONDS - $lrbell_timestamp < $lrbell_duration )) && return 0 print -n '\a' if [ -n "$DISPLAY" ] && [ -n "$lrbell_window_id" ]; then if [ "$(lrbell_active_window_id)" != "$lrbell_window_id" ]; then notify-send "Command finished" "$lrbell_message" fi fi } add-zsh-hook preexec lrbell_begin add-zsh-hook precmd lrbell_end \end{minted} \url{https://github.com/rcaloras/bash-preexec} \end{frame} \section[Section]{Bash doplňování} \begin{frame}[fragile]{Jednoduchý příklad} \scriptsize \begin{minted}[frame=lines]{shell} _sterm() { local cur prev _init_completion || return COMPREPLY=() local ops="-h --help -c -d -e -n -r -s -v" case "$prev" in -d|-r) ;; -s) local speeds="2400 4800 9600 19200 38400 57600 115200 230400" COMPREPLY+=($(compgen -W "${speeds}" -- ${cur})) ;; *) COMPREPLY+=($(compgen -W "${ops}" -- ${cur})) ;; esac } complete -o default -F _sterm sterm \end{minted} \end{frame} \begin{frame}[fragile]{gitbmerge doplňování} \scriptsize \begin{minted}[frame=lines]{shell} _gitbmerge() { local cur prev _init_completion || return [ $COMP_CWORD -gt 1 ] && return # Complete only single dependency COMPREPLY=() local GDIR="$(pwd)" while [ ! -d "$GDIR/.git" ]; do [ -z "$GDIR" ] && return GDIR="${GDIR%/*}" done GDIR="$GDIR/.git" [ -f "$GDIR" ] && GDIR="$(cat "$GDIR")" [ -d "$GDIR/refs/heads" ] || return local ops="" for B in "$GDIR"/refs/heads/*; do ops="$ops ${B#$GDIR/refs/heads/}" done COMPREPLY+=($(compgen -W "${ops}" -- ${cur})) } complete -F _gitbmerge gitbmerge \end{minted} \end{frame} \begin{frame} \Huge A jaké tipy máte vy? \Large Děkuji za pozornost. % Poznamka ze vse je take pro zsh v mem gitu \end{frame} \end{document}