Wie überprüfe ich, ob mehrere Dateien vorhanden sind?

Wie überprüfe ich, ob mehrere Dateien vorhanden sind?

Ich habe ein Shell-Skript, das nach einer Datei sucht /tmp/bbsnode1und diese löscht, wenn die Existenz dieser Datei bestätigt wird. Ich möchte alle vorhandenen Dateien ( /tmp/bbsnode2,, /tmp/bbsnode3und ) löschen./tmp/bbsnode4Löschen Sie sie aber nur, wenn alle vorhanden sind.

Folgendes habe ich bisher:

if [ -f /tmp/bbsnode1 ]
then
/usr/bin/rm /tmp/bbsnode1
fi

Antwort1

Ich würde eine Shell verwendenFunktionhierfür anstelle eines Skripts:

rm-all-or-none() {
  for f; do
    [ -f "$f" ] ||
      { printf '%s is not an existing file, no files removed\n' "$f" >&2
        return 1;}
  done
  rm -fv -- "$@"
}

Dann würde ich es mit Klammererweiterung aufrufen, statt mit einem Glob. Globs werden nur in Dateien erweitert, dieexistieren, aber in diesem Fall möchten wir die Dateien angeben und sie nur entfernen, wennalledavon gibt es:

rm-all-or-none /tmp/bbsnode{1..4}

Längere gleichwertige Version:

rm-all-or-none() {
  for f in "$@"; do
    if [ -f "$f" ]; then
      :
    else
      printf '%s is not an existing file, no files removed\n' "$f" >&2
      return 1
    fi
  done
  rm -fv -- "$@"
}

Siehe auch:

Antwort2

Sie können einen beliebigen Befehl verwenden, um lsnach den Dateien zu suchen und sie in einer Zeile zu löschen

ls /tmp/bbsnode{1,2,3,4} &>/dev/null && rm /tmp/bbsnode{1,2,3,4}

Beachten Sie, dass es im Allgemeinen unsicher ist, solche Dinge in /tmp zu tun, da jeder andere Benutzer widersprüchliche Dateien mit denselben Namen erstellen könnte.

Eine kurze Erklärung:

Der Rückgabewert von lsist ungleich Null, wenn eine der Dateien nicht existiert. Das {1,2,3,4}ist eine Klammererweiterung: es wird für jede Zahl zu einem String erweitert: /tmp/bbsnode{1,2,3,4}ist also dasselbe wie /tmp/bbsnode1 /tmp/bbsnode2 /tmp/bbsnode3 /tmp/bbsnode4. Das &&führt den nächsten Befehl nur aus, wenn der vorherige Befehl einen Rückgabewert von Null hatte, und rmwird daher hier nur ausgeführt, wenn alle 4 Dateien existieren. Schließlich &> /dev/nullunterdrückt das die Ausgabe von ls( &>leitet sowohl stdoutals auch um stderr, /dev/nullentfernt sie).

Unten eine weitere Lösung mit nur Shell-Builtins. Sie ähnelt der Antwort anderer, jedoch ohne zusätzliche Funktion oder Skript:

set -- /tmp/bbsnode{1,2,3,4}
(for f; do test -f "$f" || exit; done) && rm -- "$@"

Antwort3

In diesem speziellen Fall könnten Sie Folgendes tun:

set -- file[1-4]
[[ $# -eq 4 ]] && rm -f -- "$@"

Dies setist die Argumentliste für die Dateinamen, die mit einem der Werte file1, file2, file3oder file41 übereinstimmen. Dann rmwerden diese Dateien nur dann ausgeführt, wenn die Anzahl der Argumente 4 ergibt, d. h. wenn alle Dateien vorhanden sind.


1: der Einfachheit halber verwende ich filestatt/tmp/bbsnode

Antwort4

Sie können dieses Skript mit dem Namen verwendenremoving_group

#!/usr/bin/bash

function check {
    while (( "$#" )) ; do
        if [ -f "$1" ] ; then
            # echo "The file $1" ;
            shift ;
        else
            # echo "The's no file $1";
            return 1
        fi
    done
    return 0
}

if check $@; then
    while (( "$#" )) ; do
        # echo "Remove $1" ;
        rm "$1" ;
        shift ;
    done
fi

Die checkFunktion prüft, ob alle Argumente normale Dateien sind. Wenn die nächste Datei nicht existiert, kehrt die Funktion zurück 1und es passiert nichts. Wenn alle Dateien existieren, 0wird process zurückgegeben if check $@, das die Dateien einzeln entfernt. Die zu prüfenden und zu entfernenden Dateien werden als Parameter in der Befehlszeile beschrieben, zum Beispiel

./removing_group /tmp/bbsnode1 /tmp/bbsnode2 /tmp/bbsnode3 /tmp/bbsnode4

oder

./removing_group /tmp/bbsnode{1,2,3,4}

verwandte Informationen