2017-07-05 1 views
2

Ich lese Strings aus einer Blacklist-Datei, die Dateien und Ordner enthält, die gelöscht werden sollen. Es funktioniert für einfache Dateinamen, aber nicht für Platzhalter.erweitern Platzhalter in Zeichenfolge Variable

z. Wenn ich auf die Shell rm -rf !(abc|def) tippe, löscht es alle außer diesen beiden Dateien. Wenn diese Zeichenfolge !(abc|def) in die Blacklist gesetzt wird, funktioniert sie nicht, da die Zeichenfolge nicht ausgewertet wird.

Also habe ich versucht, eval zu verwenden, aber es funktioniert nicht wie erwartet.

#!/bin/bash 
# test pattern (normally read from blacklist file) 
LINE="!(abc|def)" 

# output string 
echo "$LINE" 

# try to expand this wildcards 
eval "ls $LINE" 

# try with subshell 
(ls $LINE) 

Wie kann ich das funktionieren lassen?

+0

'Ich lese Strings aus einer Blacklist-Datei': Wie? Ihr Code zeigt diesen Teil nicht an. – sjsam

+0

Sie sind besser dran, indem Sie mit -regex und -delete dafür suchen. –

+0

sjsam, ich habe diesen Teil nicht gezeigt, weil er nichts mit meinem Problem zu tun hat. Ich habe ein abgespecktes Skript vorbereitet, um das Problem zu reproduzieren. – user3150128

Antwort

4

Höchstwahrscheinlich ist die Shelloption extglob für nicht interaktive Shells deaktiviert (wie die, in der das Skript ausgeführt wird).

Sie haben ein paar Dinge ändern:

#!/bin/bash 

# Turn on extglob shell option 
shopt -s extglob 

line='!(abc|def)' 

echo "$line" 

# Quoting suppresses glob expansion; this will not work 
ls "$line" 

# Unquoted: works! 
ls $line 

Sie müssen

  • wiederum auf der extglob Shell Option
  • Verwendung $line unquoted: zitiert unterdrückt Expansion glob, die fast ist immer gewünscht, aber nicht hier

Beachten Sie, dass ich Kleinbuchstaben Variablennamen verwende. Großbuchstaben sind für Shell- und Umgebungsvariablen reserviert. die Verwendung von Kleinbuchstaben verringert die Wahrscheinlichkeit von Namenskonflikten (siehe POSIX spec, vierter Absatz).

Auch eval wird hier nicht benötigt.

+0

Nun, das könnte das Problem lösen. Ich bin jedoch gespannt, wie das Programm diese Dateinamen aus der Blacklist-Datei liest. :) – sjsam

+2

@sjsam Ja, könnte auch ein X/Y-Problem sein;) –

+0

Vielleicht möchten Sie erwähnen, dass Sie in eine Bash-Array-Variable (zB 'a = ($ line)' oder iterate (portable) mit 'for erweitern können ', sondern um die in der Frage gezeigten' eval'- und subshell-Ansätze zu vermeiden, die die Identität der einzelnen Dateinamen verlieren. Es kann auch eine Anleitung zur Verwendung von '--' geben, um Probleme mit Namen zu vermeiden, die wie Befehle aussehen Optionen –

Verwandte Themen