QL.túra

Kulturális smörgåsbord Esterházytól Wass Albertig, a gumicsizmától az iPad-ig, a Teletabiktól Sexpírig, a makrofágtól a mikrokontrollerig, miazmás...

Címkék

2000 (20) 2001 (6) 2002 (16) 2003 (164) 2004 (61) 2005 (40) 2006 (31) 2007 (28) 2008 (33) 2009 (175) 2010 (188) 2011 (201) 2012 (86) 2013 (40) 2014 (36) 2015 (26) 2016 (10) adáshiba (91) android (1) animáció (93) cygwin (3) film (410) gezarol (13) hájtek (159) hangoskönyv (32) ipad (17) klip (12) könyv (191) linux (29) színház (169) vers (17) windows (37) zene (111) Címkefelhő

+jegyzések

Most ...

... múlok .osan

bmi_tiny.png


... hallgatom
Szabó Magda: Régimódi történet
https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcSqTmZEqlCRFgojyt52Q2n_qiMTyVlt-zJu-DpbNKVY6OQbBh4u


... olvasom
Alexander Steele (szerk.): Kezdő írók kézikönyve


... (Kik ezek? Kik ezek az embek? Kik ezek?)
profile for TrueY on Stack Exchange, a network of free, community-driven Q&A sites
free counters

[Hájtek] Bash tippek és trükkök

2014.09.02. 11:00 | TrueY | Szólj hozzá!

Címkék: linux 2014 hájtek cygwin

"Flexnek ajánlom..."

Van egypár függvény, amit minden bash-es környezetben installálni szoktam. Ilyenek az "lm" (eredetileg az "ls -l|more" rövidítése volt), a "..", "...", ... család stb. Most sikerült végre jónehány korábbról maradt ötletet lekódolnom bash alá. Hátha érdekes lehet másnak is, ezért közreadom...

  1. cd FILE
    A Total Commander-ben nagyon tetszik az a lehetőség, hogy ha egy teljes path-t másolunk be a command prompt-jába (amint mondjuk egy find kimeneteként kaptunk), akkor is odamegy, ha a path vége egy file. Ezt ültettem át bash-ba. Persze a Total Commander kijelöli a keresett file-t, amit értelemszerűen nem valósítottam meg. Még azon gondolkodom, hogy ebben az esetben beállítanám a CDFILE nevű környezeti változót (a CDPATH mintájára), de ez még nincs teljesen végiggondolva. Lássuk hát a cd renormált változatát. Nem biztos, hogy teljesen jól kezeli a -L és -P opciókat, de mivel ezeket még életemben nem használtam, ezért engem meglehetősen nagy valószínűséggel nem fog zavarni. Ímhol a módosított "cd" parancs:

    # enable cd path/file (like in Total Commander)
    cd() { [ $# -eq 0 ] && command cd;
        local arg f; declare -a arg; [[ "$1" =~ ^-[LP]$ ]] && arg=("$1") && shift
        f="$1" ; [ -f "$f" ] && f=${f%/*}; arg+=("$f"); command cd "${arg[@]}";}
    export -f cd

    Ez ha az argumentum egy file-ra mutat, akkor levágja a file-t és szépen odamegy a maradvány könyvtár névre. Egyébként meg pont úgy működik, ahogy a bash beépített cd-je.

  2. find: egyszerűbben
    Szintén régi álmom volt, hogy a "find"-nak ne kelljen megadni folyton a "-name" opciót, ha csak egy mintát keresünk. Annyit csináltam, hogy ha a megadott egyetlen arg nem egy dir, vagy symlink, vagy file, akkor átalakítja a kérést -name-esre.

    # Simplified find. With one arg just find that pattern
    find() { [ $# -eq 1 -a ! -d "$1" -a ! -L "$1" -a ! -f "$1" ] && set -- -name "$1"; command find "$@";}
    export -f find

    Szóval most már mehet a 'find *.cpp' stílusban. Akkor van gond, ha mondjuk a CVS könyvtárakat
    keressük és a cwd-ben is már ott van a CVS. Akkor expliciten meg kell adni a -name opciót. Lehet, hogy a könyvtár, symlink, file ellenőrzést el lehetne hagyni. Egyelőre nem okozott problémát, ezért így kísérleti verzióként így marad.

  3. ls: könyvtárak előre
    Engem speciel picinyként zavart, hogy ha listázom a könyvtár file-jait, akkor név szerint rendezi sorrendbe alapból. Jobban szeretem a Total Commander-es megoldást, ahol a könyvtárak elől vannak. Találtam is erre egy külön opciót, de ha régi ls(1) használunk, akkor kell egy kis kézi mókolás:

    Új bash-ban:

    lm (){ ls --color -l --group-directories-first -h "$@" | less -eRrXF;}
    export -f lm

    Régi verzió:

    # Emulate missing --group-directories-first
    lm() { ls -l --color -h "$@"|awk 'NR==1||/^d/{print;next};{f[n++]=$0}END{for(i=0;i<n;++i)print f[i]}'|less -eRrXF;}
    export -f lm

    A -h opció a méreteket kiegészíti a K, M, G-vel, így szerintem olvashatóbb. A less nem vár karakter leütést, ha egy képernyőre elfér a kimenet, illetve nem törli le a kimenetét. Továbbá átengedi az "ls --color" színező escape szekvenciáit.

  4. cd ../../..
    Már nagyon rég kimódoltam, hogy a cd ../../..  kelgyók helyett a rövidebb ".." (cd .. helyett), "..." (cd ../..), "...." (cd ../../..) stb. függvényeket használom. Szerintem nagyon intuitív és hatékony megoldás, bár sajnos a "." foglalt. (Szerénység! Ne tömjénezze magát! Szerénység!) Kifejezetten hiányolom, ha új környezetben kell téblábolnom. Egy hiányossága volt eddig. Nem lehetett command line argumentumban beírni, ha felfelé szerettünk volna menni. De most már az is megvan! Sőt az automatikus könyvtár kiegészítés is megy. Annyiban különbözik a cd-től, hogy a könyvtárakra szűkítettem a felajánlott neveket. Bár lehet, hogy az összes file kiírása meg segítené a tájékozódást (és az új cd-vel oda is tudna menni). No, majd meglátom. A korábbiakhoz képest azt is egyszerűsítettem, hogy egy for ciklus gyártja le az összes függvényt az autocomplete résszel együtt. Az alábbi részletet kell a .bash_profile-ba, vagy igény szerint a .bashrc-be kell beletenni. Az autocomplete-hez kellett egy kis segítség, amit >innen< szedtem. No meg a man bash(1)-ből.

    #
    # Auto completion function
    #

    __dotdot_completion() { local p n=${#COMP_WORDS};
      for((--n;n;--n)){ p+=../;}; IFS=$'\n';
      COMPREPLY=($(command cd $p&&command ls -d ${COMP_WORDS[1]}*/ 2>/dev/null));
    }
    export -f __dotdot_completion

    # Define a lot of .. functions
    n=..
    unset p
    for((;${#n}<10;)){ p+="../"; eval "$n(){ command cd $p\"\$1\";}";
        export -f $n; command complete -o nospace -o filenames -F __dotdot_completion $n; n+=.;
    }
    unset p n

    Így most már megy a "$ .. <TAB><TAB>", amikor is kilistázza a szülő könyvtár alatti könyvtárakat.

  5. Prompt

    Nem szeretem a feleslegesen hosszú prompt-okat, ezért én az alábbit szoktam használni. Előnye, hogy benne van a használt terminál neve (ez akkor jó, ha mondjuk a gdb-ben a kimenetet átirányítjuk) és hogy az adott bash hanyadik gyerek, azaz ^D-re becsukja-e az ablakot, vagy csak eggyel feljebb lép. Ez utóbbi tényleg nem nagyon hasznos (hiszen a bash szól, ha olyan ablakból akarunk kilépni, amelyikben vannak háttérben futó processzek), de párszor jól jön.

    export PS1="\w [\l:\j]\$ "

    És egy példa:

    ~ [2:0]$ tty
    /dev/pts/2
    ~ [2:0]$ vim
    ^Z
    [1]+  Stopped                 vim
    ~ [2:1]$ logout
    There are stopped jobs.
    ~ [2:1]$ fg
    :q
    ~ [2:0]$
  6. Közös függvények

    A függvények elején be szoktam tölteni pár perl szerűen használható függvényt. A die és warn kiírja az üzenetet és a hívó sor számát az stderr-re, az oops és damn pedig ezen felül a teljes call stack-et is kiírja. A getARGS pedig megkönnyíti a getopts beépített függvény használatát és definiál egy csomó környezeti változót ARG_<arg> formátumban. Még a helpet is legenerálja nekünk. Például ha a szkriptünk elején meghívjuk a következő sort:
    getARGS "ab:" "-a Csinál valamit" "-b FILE - Mást csinál"
    és szkriptünket meghívjuk a "-a -b Akarmi" paraméterekkel, akkor a $ARG_a értéke 1 és $ARG_b értéke 'Akarmi' lesz. A "-h"-t nem kell megadnunk, mert az alapból kezeli. Ha ilyen argumentumot talál, akkor egy hevenyészett helpet ír ki. A fel nem dolgozott argumentumokat az ARGS tömbben adja vissza (pl: olyan argumentumot talál, ami nem kötőjellel kezdődik, vagy amiket a '--' arg után adunk meg).

    #!/usr/bin/bash
    #
    # Common bash functions
    #
    # v0.004, 2014-09-09, TrueY
    #
    ########################################################

    warn() { read a b < <(caller); echo "$@ at line $b:$a" >&2;}
    die() { read a b < <(caller); echo "$@ at line $b:$a" >&2; exit 1;}
    oops() { echo "$@">&2; local n=0
      while read a b c < <(caller $n); do
        echo "  at func '$b' at line $c:$a"; ((++n));
      done >&2
    }
    damn() { echo "$@">&2; local n=0
      while read a b c < <(caller $n); do
        echo "  at func '$b' at line $c:$a"; ((++n));
      done >&2
      exit 1;
    }

    # traslate command line arguments to env var ARG_<opt>=val
    #   Older bash does not provide hash arrays
    # First arg is the accepted args, all others are for halfhearted help
    # if -h presented as arg, show help text automatically
    getARGS() {
      [ $# -eq 0 ] && warn "$FUNCNAME: Bad number of args" && return 1
      local OPTS="$1"; shift; ARGS=() # declare -a makes it local
      HELP="\nUsage: ${0##*/}"
      for((i=0;i<${#OPTS};++i)){
        local c=${OPTS:i:1}
        if [ "$c" == : ]; then HELP+=" <ARG>"
        else HELP+=" -$c"
        fi
      }
      HELP+="\n\n  -h - This help text.\n"
      for((;$#;)){ HELP+="  $1\n"; shift;}

      # BASH_ARGV is in reverse order
      for((i=${#BASH_ARGV[@]}-1;i>=0;--i)){
        [ "${BASH_ARGV[$i]}" == -h ] && echo -e $HELP && exit 0;
        ARGS+=("${BASH_ARGV[$i]}");
      }
      OPTIND=1 # Reset for any case
      while getopts "$OPTS" arg "${ARGS[@]}"; do
        [ $arg == "?" ] && echo "Use -h option for help!" && return 1
        eval "ARG_$arg='${OPTARG:-1}'"
      done
      ARGS=("${ARGS[@]:OPTIND-1}") # Get the remaining options

      return 0
    }

    Ez a file a bash szkriptek elején a ". ~/common_bash_functions" hívással tölthető be.

Hát ennyit mára a bash világából.

Definiálódjunk minden nap!

A bejegyzés trackback címe:

https://qltura.blog.hu/api/trackback/id/tr616569361

Kommentek:

A hozzászólások a vonatkozó jogszabályok  értelmében felhasználói tartalomnak minősülnek, értük a szolgáltatás technikai  üzemeltetője semmilyen felelősséget nem vállal, azokat nem ellenőrzi. Kifogás esetén forduljon a blog szerkesztőjéhez. Részletek a  Felhasználási feltételekben és az adatvédelmi tájékoztatóban.

Nincsenek hozzászólások.
süti beállítások módosítása