Wenn Sie keine Schleife schreiben, können Sie den letzten Befehl N-mal wiederholen.
Zum Beispiel kann ich den letzten Befehl einmal mit einem Doppelknall (!!) wiederholen, aber wie wiederhole ich ihn 30 Mal?
Wenn Sie keine Schleife schreiben, können Sie den letzten Befehl N-mal wiederholen.
Zum Beispiel kann ich den letzten Befehl einmal mit einem Doppelknall (!!) wiederholen, aber wie wiederhole ich ihn 30 Mal?
Antworten:
Mit zsh
und unter der Voraussetzung der letzte Befehlszeile war nur ein Befehl oder eine Pipeline oder und-oder die Liste (das ist zum Beispiel echo x
, echo x | tr x y
, echo x && echo y
, auch Verbindung Befehle wie { x; y; }
oder for
/ while
Schleifen , aber nicht echo x; echo y
):
repeat 30 !!
Verwenden Sie Folgendes, um die vorherige Befehlszeile zu wiederholen, auch wenn sie mehrere Befehle enthielt:
repeat 30 do !!; done
Oder:
repeat 30 {!!}
Mit bash
und nur für einfache Befehle (unter den obigen Beispielen nur für den echo x
Fall) können Sie eine Hilfsfunktion wie folgt definieren:
repeat() {
local n="$1"
shift
while ((n-- > 0)); do
"$@"
done
}
(und repeat 30 !!
wie oben verwenden). Ein Nebeneffekt ist, dass der Code, da er in einer Funktion ausgeführt wird, anders "$@"
aussieht "$#"
und Dinge wie typeset
anders funktionieren, sodass Sie Dinge wie:
eval 'echo "$1"'
repeat 30 !!
Ein weiterer Ansatz zur emulieren zsh
‚s repeat 30 {!!}
wäre ein Alias zu erklären , wie:
alias repeat='for i in $(seq'
(unter der Annahme eines unveränderten $IFS
)
Und dann benutze:
repeat 30); { !!; }
Das kürzeste, was ich mir einfallen lassen kann, ist:
date # or whatever command
for i in {1..30}; do !!; done
for i in {1..30};{ !!;}
Ein Ansatz könnte darin bestehen, den Zeileneditor !!;
30 Mal einzufügen .
Wie bei readline
( bash
's Zeileneditor) im vi
Modus:
!!; Escdd30p
Das emacs
Modusäquivalent funktioniert mit dem zsh
Zeileneditor, aber anscheinend nicht mit bash
's readline
. Sie können jedoch readline
stattdessen kbd-Makros verwenden, die anscheinend wiederholt werden können:
Definieren Sie das kbd-Makro wie folgt !!;
:
Ctrl+X(!!; Ctrl+X)
Was Sie später 30 Mal aufrufen können als:
Alt+3Alt+0Ctrl+Xe
Das ist ein bisschen hässlich, aber:
eval "`fc -ln -1`;: "{1..10}\;
Das führende Leerzeichen ist nicht unbedingt erforderlich, aber nützlich, um die Eingabe des eval
Befehls in den Verlauf zu unterdrücken, wenn es (oder ) $HISTCONTROL
enthält .ignorespace
ignoreboth
Alternative:
eval "fc -s $((HISTCMD-2)) "{1..10}\;
Und:
eval 'history -s '{1..10}';fc -s -2;'
Der seq
Befehl ist Teil von Standard * nix und daher nicht von Ihrer Shell abhängig. Mit ihm und dem Loop-Konstrukt Ihrer Shell können Sie Folgendes tun:
for i in $(seq 30); do !!; done
oder
for i in `seq 30`; do !!; done
Eine weitere Schleife in Bash (zB danach: https://unix.stackexchange.com/a/372487/9689 )
Machen Sie es irgendwo in Ihrem $PATH
Namen repeat
zu einer ausführbaren Datei , um einen ähnlichen Effekt wie in zsh zu erzielen ( https://unix.stackexchange.com/a/372484/9689 ):
#!/bin/bash
n=$1
shift 1
for ((x=0; x<$n; ++x)); do
"$@"
done
so später können Sie:
$ repeat 3 date
Kern: https://gist.github.com/gwpl/26fefe3a165304f3dedb21009506107f