lu.se

Datavetenskap

Lunds Tekniska Högskola

Denna sida på svenska This page in English

Användbara bash-saker

Lämpligt i .inputrc

Lägg till detta i din ~/.inputrc:
"\e[A": history-search-backward
"\e[B": history-search-forwardset 
set show-all-if-ambiguous on
set completion-ignore-case on
TAB: menu-complete

De första två raderna har med sökning bakåt i historiken att göra. Om man har gett ett kommando men inte minns mer än att det började på c så skriver man ”c” och trycker pil upp varvid den visar allt i historiken som börjar på c. (Givetvis kan man skriva mer än en enda bokstav).

De tre övriga raderna har att göra med tabb-komplettering, ta bort skiftkänslighet och möjligheten att se all historik om det man söker inte gittas.

Tillsammans kommer dessa fem saker att klart förbättra din terminaldag!

 

Lämpliga alias i .profile

alias dig='dig +search +short +identify'
Berättar vilken server som svarar och är inte så pratig

alias ls='ls -AsCFGk'
Listar alla filer utom ”.” och ”..”, färglägger och sätter tecken efter olika typer av filer; ”@”, ”*”, ”/” etc.

alias grep='grep --color=auto'
Färglägg det som fångas av grep

alias ql='qlmanage -p "$@" >& /dev/null'
Öppna en fil i QuickLook direkt från Terminal

Prompt

En enkel prompt får man med detta:
if [ "$(echo $USER)" = "root" ]; then
  PS1="\e[37;41m\D{%a %e %b, %G ■ %T} ▶ \u@\h:\w$ \e[0m \[\e];\u@\h:\w\a\]"
else
  PS1="\e[34m\D{%a %e %b, %G ■ %T} ▶ \u@\h:\w$ \e[0m \[\e];\u@\h:\w\a\]"
fi

Bra prompt: root får vit text (37) på röd (41) bakgrund, alla andra får blå text (34) i prompten. Detta är resultatet:
Ons 16 Sep, 2015 ■ 10:34:28 ▶ peterm@paravel:~$

alltså: dagnamn (%a), dagnummer (%e), månad (%e), år (%G), tid (%T) samt uid (\u), dator (\h) och katalog (\w). 

ANSI-färger finns att läsa på http://en.wikipedia.org/wiki/ANSI_escape_code m.fl. ställen). 
Den sätter även fönstertitel (den andra delen av det; användare (\u), dator (\h) och pwd (\w)). Se t.ex.: http://zipcon.net/~swhite/docs/computers/linux/shell_prompts.html

 

En mer avancerad får man med detta:
Reset="\e[0m"
ESC="\e["
BlueFont="34"
BlueBack="44"
WhiteFont="37"
WhiteBack="47"
# Set prompt
# If on Linux
if [ "$(uname -s)" = "Linux" ]; then
  if [ "$(echo $USER)" = "root" ]; then
    PS1="\e[37;41m\D{%a %e %b, %G ■ %T} ▶ \u@\h:\w$ \e[0m \[\e];\u@\h:\w\a\]"
  else
    PS1="\e[34m\D{%a %e %b, %G ■ %T} ▶ \u@\h:\w$ \e[0m \[\e];\u@\h:\w\a\]"
  # Find out distro
  # Fist: look at the /etc/*-release files
  OS_release="$(less $(ls -1 /etc/mageia-release /etc/centos-release /etc/redhat-release /etc/gentoo-release /etc/fedora-release 2>/dev/null | head -1) 2>/dev/null)"
  # If no such file, look for /etc/os-release
  if [ -z "$OS_release" ]; then
    [[ -f /etc/os-release ]] && OS_release="$(less /etc/os-release | grep PRETTY_NAME | cut -d\" -f2)"
  fi
  # If no such file, look for /etc/lsb-release
  if [ -z "$OS_release" ]; then
    [[ -f /etc/lsb-release ]] && OS_release="$(less /etc/os-release | grep DISTRIB_DESCRIPTION | cut -d\" -f2)"
  fi
  # If no such file, look for /proc/version
  if [ -z "$OS_release" ]; then
    [[ -f /proc/version ]] && OS_release="$(less /proc/version | cut -d\( -f1)"
  fi
  # OK, so it an unknown system
  if [ -z "$OS_release" ]; then
    OS_release="Unknown Linux-distro"
  fi
  printf "${ESC}${BlueBack};${WhiteFont}mWelcome to:${Reset} ${ESC}${BlueFont};${WhiteBack}m$(uname -n)${Reset} ${ESC}${BlueBack};${WhiteFont}mRunning:${Reset} ${ESC}${BlueFont};${WhiteBack}m${OS_release}${Reset} ${ESC}${BlueBack};${WhiteFont}mUptime: ${Reset} ${ESC}${BlueFont};${WhiteBack}m$(uptime | perl -ne 'm/(up .+?(?=,\ ))/; print "$1\n"' | sed 's/up //')${Reset}\n"
fi
# Else, if on macOS
elif [ "$(uname -s)" = "Darwin" ]; then
  if [ "$(echo $USER)" = "root" ]; then
    PS1="\e[37;41m\D{%a %e %b, %G ■ %T} ▶ \u@\h:\w$ \e[0m \[\e];\u@\h:\w\a\]"
  else
    PS1="\e[34m\D{%a %e %b, %G ■ %T} ▶ \u@\h:\w$ \e[0m \[\e];\u@\h:\w\a\]"
    SW_VERS="$(sw_vers -productName) $(sw_vers -productVersion)"
    ComputerName="$(networksetup -getcomputername)"
    # Find out if it's a server
    # First step: does the name from sw_vers include "server"?
    if [ -z "$(echo "$SW_VERS" | grep -i server)" ]; then
      # If not, it may still be a server. Beginning with OS X 10.8 all versions include the command serverinfo:
      serverinfo --software 1>/dev/null
      # Exit code 0 = server; 1 = NOT server
      ServSoft=$?
      if [ $ServSoft -eq 0 ]; then
        # Is it configured?
        serverinfo --configured 1>/dev/null
        ServConfigured=$?
        if [ $ServConfigured -eq 0 ]; then
          SW_VERS="$SW_VERS ($(serverinfo --productname) $(serverinfo --shortversion))"
        else
          SW_VERS="$SW_VERS ($(serverinfo --productname) $(serverinfo --shortversion) - unconfigured)"
        fi
      fi
    fi
    #Users="$(w -h | awk '{print $1 }' | uniq)"
    #UsersText="\\e[47;34m$(echo $Users | sed 's/ /\\e[0m, \\e[47;34m/g')${Reset}"
    printf "${ESC}${BlueBack};${WhiteFont}mWelcome to:${Reset} ${ESC}${BlueFont};${WhiteBack}m$(uname -n)${Reset} ${ESC}${BlueBack};${WhiteFont}mRunning:${Reset} ${ESC}${BlueFont};${WhiteBack}m${SW_VERS}${Reset} ${ESC}${BlueBack};${WhiteFont}mUptime: ${Reset} ${ESC}${BlueFont};${WhiteBack}m$(uptime | perl -ne 'm/(up .+?(?=,\ ))/; print "$1\n"' | sed 's/up //')${Reset}\n"
  fi
fi

Detta ger en prompt med samma färger som den enklare, men som dessutom när en vanlig användare loggar in berättar vad maskinen heter, vilket OS (distro för Linux) man kör och hur länge datorn har varit ”uppe” (uptime). 

Exempel 1:

Exempel 2:

Exempel 3:

Exempel 4:


export HISTTIMEFORMAT="%F %T "
Använd tidsstämplar i historiken. Presenteras som:
2012-04-16 17:17:26 kommando
men lagras i .bash_history som sekunder sedan epoch.

Starta/stoppa ARD:
alias startaARD='/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -activate -configure -access -on'
alias stoppaARD='/System/Library/CoreServices/RemoteManagement/ARDAgent.app/Contents/Resources/kickstart -deactivate -configure -access -off'

Användbar funktion: testa en fil

Denna funktion testar en fil och skriver ut dess testbara flaggor:

testt ()
{
  local dp;
  until [ -z "${1:-}" ]; do
    dp="$1";
    [[ ! -a "$1" ]] && dp="$PWD/$dp";
    command ls -lAGd "$dp";
    [[ -d "$dp" ]] && find "$dp" -mount -depth -wholename "$dp"
    for f in a b c d e f g h L k p r s S t u w x O G N;
    do
      test -$f "$dp" && help test | sed "/-$f F/!d" | sed -e 's#^[\t ]*-\([a-zA-Z]\{1\}\) F[A-Z]*[\t ]*   True if#-\1 "'$dp'" #g';
    done;
    shift;
  done
}

Exempel:

$ testt .profile
-rwxrwxr-x 1 peterm staff 3064 22 Feb 11:18 .profile
-a ".profile" file exists.
-e ".profile" file exists.
-f ".profile" file exists and is a regular file.
-r ".profile" file is readable by you.
-s ".profile" file exists and is not empty.
-w ".profile" the file is writable by you.
-x ".profile" the file is executable by you.
-O ".profile" the file is effectively owned by you.
-G ".profile" the file is effectively owned by your group.

Funktion: GeoLookup för en IP-adress

Denna funktion använder site www.geoiptool.com för att lokalisera en IP-adress geografiskt:

locate_ip() {
  curl www.geoiptool.com/en/ 2>/dev/null | awk '
  /<td.*>(Country:|City)/ {
  record="t";gsub("[\t ]*<[^>]*>",""); printf("%-1s ",$0);next;
  }
  record == "t" { gsub("[\t ]*<[^>]*>[\t ]*","");print $0;record="f";next}
  {next}
  END{print ""}'
}

Exempel: 
$  locate_ip 78.69.30.61
Country: Sweden
City: Boxholm

Patterns and pattern matching

OperatorMeaning
${variable#pattern}Om pattern matchar början av variabelns värde, tag bort den kortaste delen som matchar och returnera resten
${variable##pattern}Om pattern matchar början av variabelns värde, tag bort den längsta delen som matchar och returnera resten
${variable%pattern}Om pattern matchar slutet av variabelns värde, tag bort den kortaste delen som matchar och returnera resten
${variable%%pattern}Om pattern matchar slutet av variabelns värde, tag bort den längsta delen som matchar och returnera resten
${variable/pattern/string}
${variable//pattern/string}
Den längsta matchningen av pattern ersätts med string*
I den första formen är den endast den första förekomsten som ersätts. I den andra formen ersätts alla förekomster.

*) Om pattern börjar med # måste den matcha början av variable.
Om pattern börjar med % måste den matcha slutet av variable.
Om string är null tas matchningarna bort.
Om variable är @ eller * appliceras operationen på varje positionsparameter i tur och ordning och det expanderade är resultatet.

Sätta in defaultvärden

OperatorOm varname existerar och ≠ null, returnera dess värde, annars …
${varname:-word}returnera word
${count:-0} evalueras till 0 om count är odefinierad
${varname:=word}sätt varname till word och returnera det värdet
${count:=0} sätter count till 0 om den är odefinierad
${varname:?message}skriv ut varname: följt av message och avbryt nuvarande kommando eller script.
Utelämnar man message kommer defaultmeddelandet ”parameter null or not set”
{count:?" undefined!" } skriver ut "count: undefined!" och avslutar om count är odefinierad
${varname:+word}returnera word annars returnera null.
${count:+1} returnerar 1 (vilket skull kunna betyda "true") om count är odefinierat