blog · git · desktop · images · contact
2012-03-24
„Copy and Paste“ ist eigentlich eine schöne Sache. So per se ist das Konzept an der Shell nicht vorgesehen. Ich habe auch lange ohne es gelebt und hatte eigentlich keine Probleme, „obwohl“ ich nie einen Dateimanager an der Konsole benutzt habe. Habe einige ausprobiert, konnte mich damit aber nicht anfreunden.
Vor einiger Zeit bin ich dann im englischen Arch-Forum auf einen sehr einfachen Vorschlag gestoßen (ich finde leider das Original nicht mehr): Man kann das Konzept ja nachbauen, indem man einfach Shell-Funktionen wie diese hier definiert:
scut()
{
mv -v "$@" ~/.drag
}
scopy()
{
cp -av "$@" ~/.drag
}
spaste()
{
[[ "$(ls -A ~/.drag)" ]] || { echo "Clipboard empty." >&2; return; }
cp -avi ~/.drag/* .
}
sclear()
{
rm -Rv ~/.drag/*
}
sls()
{
ls -Ral ~/.drag
}
Das habe ich dann einige Wochen benutzt. Hat auch ganz passabel funktioniert. Besonders schön finde ich, dass es terminalübergreifend funktioniert: Ich kann in einem Terminal Dateien ausschneiden und sie in einem zweiten einfügen. Aber einige Nachteile gibt es:
Daher habe ich die Idee nun etwas anders umgesetzt. Ich lege jetzt nur noch eine Liste der Aktionen an, die durchgeführt werden sollen. Diese Liste wird in einer Textdatei gespeichert. „Aktion“ heißt: Es wird der jeweilige Dateiname und der gewünschte Vorgang („Cut“ oder „Copy“) hinterlegt. Das löst alle oben genannten Schwächen der originalen Version. Editieren kann ich die Liste dann ganz einfach mit einem Texteditor.
__scnp_rel2abs()
{
# Übernommen von sgopherd.
[[ -d "$1" ]] && { (cd -- "$1" 2>/dev/null; echo "$PWD"); return; }
[[ -f "$1" ]] && { (cd -- "${1%/*}" 2>/dev/null; echo "$PWD/${1##*/}"); return; }
}
scut()
{
for i
do
echo mv -vi
__scnp_rel2abs "$i"
done >> ~/.sdrag
}
scopy()
{
for i
do
echo cp -avi
__scnp_rel2abs "$i"
done >> ~/.sdrag
}
spaste()
{
while read -r action
do
read -r filename
printf '%7s: ' "$action"
$action "$filename" . < /dev/tty
done < ~/.sdrag
}
sclear()
{
: > ~/.sdrag
}
sedit()
{
$EDITOR ~/.sdrag
}
sls()
{
while read -r action
do
read -r filename
printf '%7s: ' "$action"
ls -ld "$filename"
done < ~/.sdrag
}
Ein neuer Nachteil tut sich auf: Meine Version funktioniert nicht bei
Dateinamen, die Newlines enthalten. Könnte man lösen, indem man in
~/.sdrag
Null-Bytes als Trenner verwendet. Das ist keine große
Änderung, aber ich war zu faul, das zu tun, weil soetwas bei mir nicht
auftaucht. ;-)
– Nachtrag zum Wörtchen „faul“. Es ist so, dass Null-Bytes die
Komplexität des meisten Codes nach oben treiben würden. Nicht viel, aber
sie würden es. Insbesondere aber würde sedit
deutlich komplexer
werden. Im Moment ist das nur ein einfacher Aufruf des Editors. Aber mit
Null-Bytes? Die kann ich nicht (oder nur schlecht) direkt im Editor
lassen. Also muss ich die Liste von der Null-Byte-Darstellung in eine
„lesbare“ Darstellung konvertieren, den Benutzer editieren lassen und
dann zurückkonvertieren. Dabei muss berücksichtigt werden, dass in
Dateinamen explizit alles außer einem Null-Byte erlaubt ist.
Hinkriegen würde man das schon. Die Frage, die sich dabei bloß stellt, ist: Lohnt es sich? Ich habe keine einzige Datei mit einem Newline im Namen auf der Platte. Daher bin ich „faul“ und lasse es bleiben, da es sich für mich nicht lohnt.
(Das ist keine Kritik an Kebas Kommentar unten, der „Einwand“ ist berechtigt. Ich wollte nur noch einmal deutlich zum Ausdruck bringen, weshalb ich das in meiner Version explizit nicht drin habe.)
– Nachtrag: Die coreutils 8.16 wurden eben released. Hier bringt
ln
jetzt die Option --relative
mit. Das finde ich sehr wichtig und
hierdurch wird eine Erweiterung der obigen Funktionen auf ln
denkbar.
Ich bräuchte nämlich möglichst einfach sowohl (symbolische) Links mit
absolutem Ziel als auch Links mit relativem Ziel. Dennoch brauche ich
die eher selten. Daher hatte ich auch diese Funktion weggelassen, weil
sie nicht gerade trivial gewesen wäre. Mit einem nun vorhandenen
--relative
sieht das aber anders aus! Da geht noch was.
– Nachtrag: Die Funktion „spaste()
“ wurde nochmal geändert. Es ist
wichtig, dass „cp
“ und „mv
“ ein Terminal haben, von dem sie lesen
können! Andernfalls können sie die Antwort für eine eventuelle „Wollen
sie das überschreiben?“-Nachfrage nicht einlesen. Kurioserweise hatte
ich bis jetzt (Ende April) keinen solchen Fall, bei dem etwas
überschrieben worden wäre, deswegen hat es einen Monat gedauert, bis mir
das aufgefallen ist.
– Nachtrag: Die Funktionen befinden sich mittlerweile als kleine
Skripte im Git-Repo und wurden auch um die Funktion „__scnp_rel2abs()
“
bereinigt:
„stouch
“ ist dafür gedacht, von der „.bashrc
“ o.ä. aufgerufen zu
werden.