Ziŝkonsiletoj 4-a: Ĝeneralhelpiloj

Esperanto · English
la 26-an de septembro 2018
Laste ĝisdatigita: la 26-an de septembro 2018

Vidpunkto meritas okdek poentojn da inteligentecaj kvocientoj.
―Alan KAY

Lastfoje, mi parolis pri la helpilaj funkcioj por asisti en la mastrumado de radikigmedioj. En ĉi tiu artikolo, mi parolos pri ĝeneralaj helpiloj por labori sur la komandlinio. Mi ankaŭ parolos pri helpemaj klavkombinoj por tajpadon plirapidigi.

Enhavotabelo

Funkcioj

Bela afero pri funkcioj, estas, ke ili estas tiel facile por skribi kaj uzi. Jen kelkaj funkcioj kiujn mi uzas ofte.

map

Kiam komandon kiu nur unu argumenton akceptas oni havas, plurajn uzojn de tiu komando oni volas simuli per ĉi tiu funkcio. Ĝi estas difinita jene:

function map () {
  for i (${argv[2,-1]}) { ${(ps: :)${1}} $i }
}

Ekzemple, je map oni povas uzi por plurajn gitaj deponejon, serie:

% map 'git clone' [email protected]:nixos/nixpkgs.git [email protected]:tmux/tmux.git

rmap

Kiel la nomo implicas, rmap funkcias kiel la inverso de map—la cetaraj argumentoj estas aplikitaj kiel komandoj al la unua argumento. Ĝi estas difinita jene:

function rmap () {
  for i (${argv[2,-1]}) { ${(ps: :)${i}} $1 }
}

Ĝi oni povas uzi, ekzemple, por diskuzadon kontroli, dosierinformon vidi, kaj la malfermajn dosiernumerojn de dosiero aŭ dosierujo vidi:

% rmap iudosierujo 'du -h' stat 'sudo lsof'

fp

Rapidan manieron por la realan kaj absolutan dosierindikon de dosiero aŭ dosierujo precizigi mi volas havi. Min ĉi tio helpas multe en skriptado. Ĝi estas difinita jene:

function fp () {
  echo "${1:A}"
}

Se mi estas en simbolligita dosierujo, kaj la realdosierindikon de . mi volas precizigi, la jenan mi povas plenumi:

% fp .

Ĉi tiu funkcio estos grava en la sekva sekcio.

d

Ofte, kiam mi iras al dosierujo, serion de komandoj mi bezonas plenumi. Tempon por tajpado mi volas savi, do anstataŭ du komandojn plenumi, nur unu mi nur devas plenumi. Manieron por dosierujon rapide ŝanĝigi tra la dosierujstakoj per pushd mi volas havi. Ĝi estas difinita jene:

function d () {
  if (( ! $#@ )); then
      builtin cd
  elif [[ -d $argv[1] ]]; then
      builtin cd "$(fp $argv[1])"
      $argv[2,-1]
  elif [[ "$1" = -<-> ]]; then
      builtin cd $1 > /dev/null 2>&1
      $argv[2,-1]
  else
    echo "$0: no such file or directory: $1"
  fi
}

Kiam je d mi kurigas sole:

% d

Mi iros al la hejmdosierujo, samkiel kion memstara cd devus fari:

Kiam je d mi plenumas kun dosierujo kaj komando:

% d ~/Downloads ls -l

La aktuala dosierujo ŝanĝiĝos al ~/Downloads, tiam je ls -l mi plenumas por la enhavon de tiu dosierujo montri.

Se la eligo de dirs -v estas la jena:

0       /usr/local
1       /tmp

Tiam, je d mi plenumu, kaj la dua enskribo estas uzota kun komando:

% d -1 date

La dosierujo ŝanĝiĝos al /tmp/, tiam la komando date kuros.

d!

Kiel la nomo implicas, d! similas al sia kuzo nur, ke se la cela dosierujo ne ekzistas, ĝin ĝi kreas, kaj la saman konduton de d ĝi faras poste. Ĝi estas difinita jene:

function d! () {
  mkdir -p $argv[1]
  d "[email protected]"
}

Ekzemple, je d! mi povas uzi por dosierujon scenigi antaŭ ISO-dosieron elŝuti:

% d! ~/Downloads/iso https://www.hundo.kato/muso/ve/ve.iso

rm!

Kiam mi certas, ke dosieron aŭ dosierujon mi volas forviŝi, mi ne volos ĝenita per invitoj, dum samtempe escepton por la hejmdosieron ne akcidente forviŝi mi volas havi. Ĝi estas difinita jene:

function rm! () {
  if [[ "$1" == "$HOME" || "$1" == "$HOME/" || "$1" == "~" || "$1" == "~/" ]]; then
      return 1
  else
    command rm -rf [email protected]
  fi
}

La komando commando certigas, ke la sistemduumdosieron rm mi alvokas anstataŭ ia ŝela alinomo aŭ funkcio.

rm+

Kiam arbon kiu multe da dosiero kaj dosierujo havas mi volas rapide forviŝi, la komandon parallel mi uzas por la forviŝadon kurigi paralele, anstataŭ serie. Ĝi estas difinita jene:

function rm+ () {
  parallel --will-cite 'rm -rf {}' ::: [email protected]
}

La pakmastrumilon de la sistemo kontrolu kiel je parallel instali.

[email protected]

Kelkfoje, dosieron aŭ dosierujon mi bezonas forviŝi sen la ŝancoj de retrovado. Por tion fari, la komandon shred mi uzas. Ĝi estas difinita jene:

function [email protected] () {
  if [[ -d $1 ]]; then
      find $1 -type f -exec shred -vfzun 10 {} \;
      command rm -rf $1
  else
    shred -vfzun 10 $1
  fi
}

La pakmastrumilon de la sistemo kontrolu kiel je shred instali.

def_mk

Helpilojn ci tiu helpilo generas. Onin ĝi permesas por funkciojn krei kiuj antaŭproduktajn dosierojn kreas antaŭ la vera komando estas plenumita. Ĝi estas difinita kiel:

function def_mk () {
  eval "function ${argv[1]} () {
            if [[ \$# -ge 2 ]]; then
                if [[ ! -e \${@: -1} ]]; then
                     mkdir -p \${@: -1}
                fi

                command ${argv[2,-1]} \[email protected]
            fi
        }"
}

Por ĝin uzi, la nomon de la funkcio kiu estos uzita kiel komando donu, kaj la malvolvo mem. Ĉi tiuj alvokoj estas ideale difinita en la agorddosiero.

cp!

Por je def_mk uzi kun cp ĝin alvoku jene:

def_mk cp! cp -rf

kiu malvolvas al:

function cp! () {
  if [[ $# -ge 2 ]]; then
    if [[ ! -e ${@: -1} ]]; then
      mkdir -p ${@: -1}
    fi
    command cp -rf [email protected]
  fi
}

Onin la komando cp! permasas por dosierojn kaj dosierujojn kopii, la celan dosierujon kreante kiel necese:

%  tree
.
├── bar.txt
└── foo.txt

0 directories, 2 files

%  cp! * a

%  tree
.
├── a
│   ├── bar.txt
│   └── foo.txt
├── bar.txt
└── foo.txt

1 directory, 4 files

mv!

Por je def_mk uzi kun mv ĝin alvoku jene:

def_mk mv! mv -f

kiu malvolvas al:

function mv! () {
  if [[ $# -ge 2 ]]; then
    if [[ ! -e ${@: -1} ]]; then
      mkdir -p ${@: -1}
    fi
    command mv -f [email protected]
  fi
}

Onin la komando mv! permasas por dosierojn movi al dosierujo, la celan dosirujon kreante kiel necese:

%  tree
.
├── bar.txt
└── foo.txt

0 directories, 2 files

%  mv! * b

%  tree
.
└── b
    ├── bar.txt
    └── foo.txt

1 directory, 2 files

Klavkombinoj

Ekster la komandoj kiuj estas tajpitaj, klavkombinoj oni ankaŭ povas alvoki por ajnajn komandojn fari. Jen kelkaj, kiujn mi uzas ofte:

insert-last-word

Kiam la lastan vorton de la lasta komando mi volas enmeti, je insert-last-word mi vokas. Ekzemple, se la jenan oni havas, en kiu la ĉapelo estas la tajpmontrilo:

% dig hundo12345.kato.muzo.io
% mtr
      ^

Kiam je M-x insert-last-word EN mi plenumas, la lastan vorton de la lasta komando ĝi enmetas, ĝin fari al:

% dig hundo12345.kato.muzo.io
% mtr hundo12345.kato.muzo.io
                             ^

Ĉi tio certigas, ke la argumento estas ĝuste kopiita.

La klavo estas defaŭlte bindita al M-.. Se oni volas certigi, ke tiun klavkombinon oni havas, la jenan metu en la agordo:

bindkey "\e." insert-last-word

copy-prev-shell-word

Se la lastan vorton en la aktuala komandlinio mi volas ripeti, je copy-prev-shell-word mi alvokas. Ekzemple, se la jenan oni havas:

% cp cxi.tio.estas.tre.longa.nomo
                                  ^

Kiam je M-x copy-prev-shell-word EN mi plenumas, la lastan vorton ziŝo enmetas, gin fari al:

% cp cxi.tio.estas.tre.longa.nomo cxi.tio.estas.tre.longa.nomo
                                                              ^

Ĝin mi bindis al M-=. Por ĝin bindi al la agorddosiero:

bindkey "\e=" copy-prev-shell-word

Anstataŭigoj

Krome la plenumado de M-x komandoj, onin ziŝo permesas por klavkombinojn difini kiu ajnan tekston enmeti sur la komandlinion, inkluzive stirsignoj.

La eligon de komandoj mi ofte bezonis akiri. Kutime la jenan mi faras:

% foo `some command`

% foo $(some command)

La antaŭa pli facilas por tajpi, tamen ĝi ne povas nestiĝi; la ĉi tiu estas tro malfacila por tajpi. Por tio, la klavkombinon M-` mi bindis jene:

% bindkey -s '\e`' '$()\C-b'

Do, se la jenan mi havas:

% foo
      ^

Kiam je M-` mi premas, la jenan mi akiros:

% foo $()
        ^

Citiloj

La bezonon por la argumenton de komandon citi mi ofte havas, precipe se metaesprimojn ĝi havas. Ofta kazo estas de jutubaj retadresoj, kiu la ? signon havas:

Por tio, je M-' bindis kiel jene:

% bindkey -s "\e'" "''\C-b"

Do, kiam la jenan mi havas:

% youtube-dl
             ^

Kiam je M-' mi premas, la jenan mi akiros:

% youtube-dl ''
              ^

Anstataŭ tri klavojn premi sur mia klavaro, nur du mi nur devas premi, kaj ĝi certigas, ke paron de citiloj mi akiras.

Ĉion rikolti

Jen ĉiom da difinoj, kun kelkaj aldonaj helpiloj, en unu loko:

function map () {
  for i (${argv[2,-1]}) { ${(ps: :)${1}} $i }
}

function rmap () {
  for i (${argv[2,-1]}) { ${(ps: :)${i}} $1 }
}

function fp () {
  echo "${1:A}"
}

function d () {
  if (( ! $#@ )); then
      builtin cd
  elif [[ -d $argv[1] ]]; then
      builtin cd "$(fp $argv[1])"
      $argv[2,-1]
  elif [[ "$1" = -<-> ]]; then
      builtin cd $1 > /dev/null 2>&1
      $argv[2,-1]
  else
    echo "$0: no such file or directory: $1"
  fi
}

function d! () {
  mkdir -p $argv[1]
  d "[email protected]"
}

function rm! () {
  if [[ "$1" == "$HOME" || "$1" == "$HOME/" || "$1" == "~" || "$1" == "~/" ]]; then
      return 1
  else
    command rm -rf [email protected]
  fi
}

function rm+ () {
  parallel --will-cite 'rm -rf {}' ::: [email protected]
}

function [email protected] () {
  if [[ -d $1 ]]; then
      find $1 -type f -exec shred -vfzun 10 {} \;
      command rm -rf $1
  else
    shred -vfzun 10 $1
  fi
}

function def_mk () {
  eval "function ${argv[1]} () {
            if [[ \$# -ge 2 ]]; then
                if [[ ! -e \${@: -1} ]]; then
                     mkdir -p \${@: -1}
                fi

                command ${argv[2,-1]} \[email protected]
            fi
        }"
}

def_mk cp! cp -rf
def_mk mv! mv -f

function def_key () {
  while [[ $# -ge 2 ]]; do
    bindkey "$1" "$2"
    shift 2
  done
}

function def_keys () {
  def_key $keys
  unset keys
}

function def_out_key () {
  while [[ $# -ge 2 ]]; do
    bindkey -s "$1" "$2"
    shift 2
  done
}

function def_out_keys () {
  def_out_key $out_keys
  unset out_keys
}

keys=(
  "\e." insert-last-word
  "\e=" copy-prev-shell-word
); def_keys

out_keys=(
  '\e`' '$()\C-b'
  "\e'" "''\C-b"
); def_out_keys

Finrimarkoj

La komandlinion uzante, precipe per ŝelo tiel potenca kiel ziŝo, estas devige por esti konscie, kiun la ŝelon povas fari. Pakojn kiuj la ŝelon tajloras ne blinde uzu, sen kompreni kiujn ili faras.

Bonan ziŝigadon!