So erkennen Sie, ob Eingaben von Argumenten, Dateien oder Terminals stammen

8

Gibt es in bash eine Möglichkeit festzustellen, ob ein bestimmtes Skript aufgerufen wurde mit:

$ myscript.sh myfile

oder:

$ myscript.sh < myfile

In einigen Skripten habe ich immer auf den Inhalt von myfilewith zugegriffen $1, aber jetzt möchte ich das Verhalten in verschiedenen Fällen ändern.

EDIT: Ich möchte auch einen dritten Fall, wenn er ohne Weiterleitung aufgerufen wird:

$ myscript.sh
mschonaker
quelle

Antworten:

13

BEARBEITEN : geändert -tin -t 0, wodurch Eingaben vom Terminal oder der Datei korrekt erkannt werden.

Ich denke, der Schlüssel hier ist zu wissen, ob Ihre Eingabe von einem Terminal oder von einer Datei kommt. Hierfür gibt es einen Test ( man testsiehe -t).

Angenommen, Sie führen ein Bash-Skript aus:

if [ -t 0 ]; then
    echo "Input from terminal"
    if [ $# -eq 0 ]; then
        echo "No input files specified on command line.  Error." >&2
    else
        echo "Input file given on command line.  It is $1"
    fi
else
    echo "Input coming from stdin"
fi

Sie können die verschiedenen Szenarien behandeln, indem Sie die obigen Echoanweisungen durch tatsächlichen Code ersetzen.

Update, Quickie-Testskript:

#!/bin/bash
[ -t 0 ] && echo "t is true" || echo "t is false"

Laufen:

$ test.sh testfile
t is true
$ test.sh < testfile
t is false
$
unpythonisch
quelle
-t wird immer als wahr ausgewertet, < myfile
wenn
@mschonaker - Verwenden -t 0liefert die richtigen Ergebnisse. Antwort aktualisiert.
unpythonic
@ MarkMann Was macht das 0? Was ist der Unterschied? Es ist nicht in der Dokumentation.
Ivan V.
1
@IvanV. - Die Null ist der zu testende Dateideskriptor. Standardeingabe ist zugeordnet 0, Standardausgabe mit 1und Standardfehler mit 2. Wenn ich überprüfen wollte, ob meine Ausgabe an ein Terminal geht, würde ich verwenden[ -t 1 ]
unpythonic
@ MarkMann Danke, ich dachte, es könnte das sein oder eine Art Boolescher Check.
Ivan V.
6

Im Allgemeinen sind die Ausdrücke $1, $2erweitern usw. zum 1., 2., usw. Argument auf der Linie Script - Befehl gegeben.

Wenn Sie also ein Skript aufrufen als:

myscript.sh myfile

dann $1im Skript erweitert zu myfile(und $2, $3usw. alle die leeren Zeichenkette sind).

Wenn Sie ein Skript aufrufen als:

myscript < myfile

Die Umleitung von STDIN von myfileerfolgt über die übergeordnete Shell, sodass das Skript tatsächlich ohne Argumente aufgerufen wird und $1auf die leere Zeichenfolge erweitert wird.

Riccardo Murri
quelle
Wie erkenne ich, wenn ich ohne Argumente in der Befehlszeile aufgerufen werde (dritter Fall)? Entschuldigung, wenn Sie vor meiner Bearbeitung geantwortet haben. Vielen Dank.
mschonaker