[Um von Bash zu Ruby und Python3 zu wechseln Ich habe mehr Verarbeitung mit Bash <-> Ruby <-> Python3 (eingeführt auf einer anderen Site) verglichen. ](Https://debimate.jp/2020/04/05/bashshell-script%e3%81%8b%e3%82%89ruby%e3%82%84python%e3%81%ab%e4%b9%97% e3% 82% 8a% e6% 8f% 9b% e3% 81% 88% ef% bc% 81% e9% a0% bb% e7% b9% 81% e3% 81% ab% e4% bd% bf% e3% 81% 86% e5% 87% a6% e7% 90% 86% e3% 82% 92% e5% 90% 84% e8% a8% 80 /)
Dieser Artikel beschreibt, was ich recherchiert habe, um Bash Script durch Python 3.x zu ersetzen. Die Motivation, über Ersatz nachzudenken, war, dass ich dachte, dass "Bash Script über 300 Schritte mich erwürgen würde".
Ich verstehe die Stärken von Bash. Mit Ausnahme der eingebetteten Umgebung funktioniert es garantiert mit den wichtigsten Distributionen und Wenn Sie unter Berücksichtigung der POSIX-Kompatibilität schreiben, wird die Anzahl der Korrekturen zum Zeitpunkt der Portierung reduziert. Vor allem vielen Entwicklern bekannt, bedeutet dies eine große Anzahl von Personen (Mitgliedern), die das Skript ändern können. Aber aus praktischen Gründen schreibe ich Bash angesichts der oben genannten Vorteile nicht. Da ich es erstelle, ohne darüber nachzudenken, werde ich zu einem späteren Zeitpunkt Schmerzen sehen (Beispiel: der folgende Ablauf).
Basierend auf dieser Realität und den Ratschlägen von Google (siehe unten) Wir sind zu dem Schluss gekommen, dass "Python 3.x ab 2017".
Original: Quelle "Shell Style Guide" If you are writing a script that is more than 100 lines long, you should probably be writing it in Python instead. Bear in mind that scripts grow. Rewrite your script in another language early to avoid a time-consuming rewrite at a later date.
Übersetzung Wenn Sie ein Skript schreiben, das> 100 Zeilen oder länger ist, sollten Sie es wahrscheinlich stattdessen in Python schreiben. Beachten Sie, dass das Skript wächst. In einer anderen Sprache, um später zeitaufwändige Korrekturen zu vermeiden Bitte schreiben Sie das Skript so schnell wie möglich neu.
・ Debian 8.6 (64 Bit) ・ Bash (GNU Bash 4.3.30) ・ Python (Version 3.5.1, Anaconda 4.0.0)
Im Fall von Bash können Sie es ausführen, indem Sie den Befehl und die Option so schreiben, wie sie im Skript sind. Führen Sie für Python das Modul subprocess aus.
Ein Beispiel für die Verwendung eines externen Befehls (Größenänderungsbefehl) (Bash, Python) ist wie folgt.
sample.sh
#!/bin/bash
resize -s 30 50 #30 Zeichen pro Zeile, 50 Zeilen
sample.py
#!/usr/bin/env python3
-*- coding: utf-8 -*-
import subprocess
#Befehle, die Sie an Unterprozesse übergeben möchten+Optionen auflisten
#Zustand einschließlich Raum(run(["resize -s 30 50"]))Fehler, wenn in beschrieben
subprocess.run(["resize","-s","30","50"])
Ein Beispiel für das Verbinden eines externen Befehls und einer Pipe ist wie folgt. Im Vergleich zu Bashs "|" - Notation gibt es mehr Inhalt zu beschreiben.
sample.py
#!/usr/bin/env python3
import subprocess
#Verbinden Sie die Standardausgabe und die Pipe für den Standardfehler, indem Sie das zweite und dritte Argument angeben.
result = subprocess.Popen(["resize","-s","30","50"], \
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = result.communicate() #Holen Sie sich Standardausgabe, Standardfehler
print("Standardausgabe:%s" % out.decode('utf-8')) #Wenn keine Dekodierungsverarbeitung durchgeführt wird, wird diese als Byte behandelt.
print("Standart Fehler:%s" % err.decode('utf-8'))
Ein Beispiel für das Schreiben des Ausgabeergebnisses eines externen Befehls in eine Textdatei lautet wie folgt. Außerdem wird das Ausführungsergebnis von "python sample.py" angezeigt.
sample.py
#!/usr/bin/env python3
import subprocess
#Protokolldatei geöffnet(command.log)Fluss bis Standardausgabe geschrieben wird
# "communicate()"von[0]部分は、複数von返り値von中から標準出力を受け取るためvon記述
log_file = open("command.log", "w")
result = subprocess.Popen(["resize","-s","30","50"], stdout=subprocess.PIPE)
log_file.write(result.communicate()[0].decode('utf-8'))
log_file.close()
#Wenn Sie hinzufügen möchten"a"Öffnen Sie die Datei durch Angabe.
log_file = open("command.log", "a")
result = subprocess.Popen(["ls", "-l"], stdout=subprocess.PIPE)
log_file.write(result.communicate()[0].decode('utf-8'))
log_file.close()
command.log
COLUMNS=50;
LINES=30;
export COLUMNS LINES;
Insgesamt 16
-rw-r--r--1 nao nao 44 24. Dezember 19:15 command.log
-rw-r--r--1 nao nao 543 24. Dezember 15:58 python_bash.txt
-rwxr-xr-x 1 nao nao 673 24. Dezember 19:15 sample.py
-rwxr-xr-x 1 nao nao 77 24. Dezember 15:58 sample.sh
Sie haben die Möglichkeit, beim Erstellen von Beispieldateien und Vorlagen Hördokumente zu verwenden. Unten finden Sie ein Beispiel für die Verwendung der Dokumente Bash und Python.
sample.sh
#!/bin/bash
VAR="check"
#Geben Sie den Inhalt des hier gezeigten Dokuments aus.Ausgabe an txt.
cat << EOS > output.txt
①
Der Umfang dieser Dokumente ist"<< EOS"Die Zeile nach der Zeile, die an den Befehl übergeben wurde(①)Von
Dann alleine"EOS"Eine Zeile über der Zeile wo(②)Bis.
Der EOS-Teil kann aber eine freie Zeichenkette sein
Die gleiche Zeichenfolge muss am Anfang und am Ende des Anhörungsdokuments verwendet werden.
$VAR #Bei Verwendung von Variablen in Hördokumenten.
\$VAR #Wenn nicht als Variable ausgegeben.
②
EOS
sample.py
#!/usr/bin/env python3
VAR="check"
#Am Ende des hier vorliegenden Dokuments[1:-1]Wenn dies nicht der Fall ist, werden vor und nach der Zeichenfolge Leerzeilen eingefügt.
heredoc = """
Im Python-Hear-Dokument
Schließen Sie die Zeichenfolge mit drei doppelten Anführungszeichen ein.
Wenn Sie Variablen in Ihrem Dokument erweitern möchten
{VAR}
Ich werde es als solches beschreiben.
Und die Variable in der Zeichenfolge ist das Funktionsformat()Wird mit erweitert.
"""[1:-1].format(**locals()) # **Wörterbuchvariablen nach Spezifikation{'VAR':"check"}Empfangen bei.
output = open("output.txt", "w")
output.write(heredoc)
output.close
Im Folgenden finden Sie drei Beispiele für die Erfassung von Benutzereingaben in der folgenden Tabelle.
Anzahl der einzugebenden Zeichen | Echo zurück | Enter(Entscheidung)Benötigen für | |
---|---|---|---|
Beispiel 1 | Keine Begrenzung | Ja | notwendig |
Beispiel 2 | Keine Begrenzung | Keiner | notwendig |
Beispiel 3 | Ein Brief | Keiner | Nicht notwendig |
sample.sh
#!/bin/bash
echo -n "Bitte geben Sie Zeichen ein:" #Möglichkeit"-n"Unterdrückt Zeilenumbrüche
read USER_INPUT
echo "${USER_INPUT}"
echo -n "Eingangsempfang ohne Echo zurück:"
stty -echo #Echo wieder AUS
read USER_INPUT
stty echo #Echo wieder EIN
echo "${USER_INPUT}"
echo -n "Ein-Buchstaben-Eingangsempfang. Nein Eingabe erforderlich:"
read -s -n 1 USER_INPUT #Nur Bash
echo "${USER_INPUT}"
sample.py
#!/usr/bin/env python3
import os
import getch # "pip install getch"Es ist notwendig, mit zu installieren.
print("Bitte geben Sie Zeichen ein:", end="")
user_input = input()
print(user_input)
#Zusätzlich zu den folgenden Methoden getpass des getpass-Moduls()Wenn du benutzt
#Sie können Eingaben ohne Echo zurück akzeptieren.
#Standardmäßig jedoch auf dem Terminal"Password:"Es wird angezeigt.
print("Eingangsempfang ohne Echo zurück:", end="")
os.system("stty -echo")
user_input = input()
os.system("stty echo")
print(user_input)
print("Ein-Buchstaben-Eingangsempfang. Nein Eingabe erforderlich:", end="")
user_input = getch.getch()
print(user_input)
Im Folgenden werden nur die Textfarben für Fehlermeldung (rot) und Warnmeldung (gelb) angezeigt. Auf der Bash-Seite scheint es einfacher zu sein, eine Funktion zu verwenden, die eine Zeichenfolge mit einer Pipe anstelle eines Arguments übergeben kann. Da es sich um ein Beispiel handelt, werden Argumente übergeben.
sample.sh
#!/bin/bash
function error_message (){
echo -n -e "\033[31m\c" #Escape-Sequenz, um Buchstaben rot zu machen
echo "$1"
echo -n -e "\033[m\c" #Stellen Sie die Textfarbe wieder her
}
function warning_message (){
echo -n -e "\033[33m\c" #Escape-Sequenz, um Buchstaben gelb zu machen
echo "$1"
echo -n -e "\033[m\c" #Stellen Sie die Textfarbe wieder her
}
error_message "error"
warning_message "warning"
sample.py
#!/usr/bin/env python3
def error_message(message):
print("\033[31m%s\033[0m" % message)
def warning_message(message):
print("\033[33m%s\033[0m" % message)
error_message("error")
warning_message("warning")
Das folgende Beispiel zeigt, wann beim Ausführen von Script Administratorrechte erforderlich sind.
sample.sh
#!/bin/bash
#Überprüfen Sie die Ausführungs-UID und UID."0"(root)In diesem Fall verfügen Sie über Administratorrechte.
# ":-"Teil${EUID}Wenn es keinen Wert in gibt${UID}Bedeutet, den Wert von zu ersetzen
if [ ${EUID:-${UID}} = 0 ]; then
echo "Sie haben Administratorrechte."
else
echo "Sie benötigen Administratorrechte, um dieses Skript auszuführen."
fi
sample.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
#Überprüfen Sie, ob Sie über Administratorrechte verfügen, indem Sie die UID und die EUID abrufen.
if os.getuid() == 0 and os.geteuid() == 0:
print("Sie haben Administratorrechte.")
else:
print("Sie benötigen Administratorrechte, um dieses Skript auszuführen.")
Verwenden Sie für Bash getopts, um die Optionen zu interpretieren. Wenn zu diesem Zeitpunkt das Skript mit einer nicht definierten Option ausgeführt wird, Eine Fehlermeldung wird automatisch angezeigt. Das Beispielskript und das Ausführungsergebnis sind unten aufgeführt.
sample.sh
#!/bin/bash
#getopts übergibt ein optionales Zeichen als erstes Argument.
#Diese Option(Beispiel:"d")Unmittelbar nach dem Optionszeichen, wenn ein Argument verwendet wird":"Schreiben(Beispiel:"d:")。
#Im folgenden Beispiel"d"Wann"f"が引数を必要Wannするオプションです。
while getopts d:f:h OPT
do
case $OPT in
d) DIR_NAME=$OPTARG #Optionale Argumente werden in der Variablen OPTARG gespeichert.
;;
f) FILE_NAME=$OPTARG
;;
h) echo "Die Verwendung des Skripts ist xxx."
exit 0
;;
*) echo "Die Verwendung des Skripts ist xxx." #Wenn eine Option kommt, die nicht angegeben ist
exit 1
;;
esac
done
echo "Verzeichnisname:${DIR_NAME}"
echo "Dateiname:${FILE_NAME}"
Ausführungsergebnis.
$ bash sample.sh -f file_name -d directory_name
Verzeichnisname: Verzeichnis_name
Dateiname: Datei_name
$ bash sample.sh -f
sample.sh:Optionen erfordern Argumente-- f
Die Verwendung des Skripts ist xxx.
$ bash sample.sh -k
sample.sh:Illegale Option-- k
Die Verwendung des Skripts ist xxx.
Für Python3 bietet das Modul argparse einen leistungsstarken Mechanismus. Sie müssen keine Funktion schreiben, um Hilfe auszugeben, und im Gegensatz zu Bash können Sie die Option long verwenden. Das Beispielskript und das Ausführungsergebnis sind unten aufgeführt.
sample.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
#Funktion hinzufügen_argument()Optionen hinzufügen mit.
#Zwei Arten von Notationen gleichzeitig(Beispiel:"-d"、"--dir")Kann registriert werden.
#Typ ist der Typ des optionalen Arguments, dest ist das optionale Argument(Wert)Schreiben Sie den Namen der gespeicherten Variablen.
#Hilfe, die Auswirkungen dieser Option(Text, der während der Hilfe angezeigt werden soll)Wird beschrieben.
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--dir", type=str, dest="dir",
help="Schreiben Sie den in Script verwendeten Verzeichnisnamen")
parser.add_argument("-f","--file", type=str, dest="file",
help="Schreiben Sie den in Script verwendeten Dateinamen")
args = parser.parse_args()
print("Verzeichnisname:%s" % args.dir)
print("Dateiname:%s" % args.file)
Ausführungsergebnis.
$ python sample.py -d directory_name -f file_name
Verzeichnisname: Verzeichnis_name
Dateiname: Datei_name
$ python sample.py -h
usage: sample.py [-h] [-d DIR] [-f FILE]
optional arguments:
-h, --help show this help message and exit
-d DIR, --dir Schreiben Sie den in DIR Script verwendeten Verzeichnisnamen
-f FILE, --Datei Schreiben Sie den in FILE Script verwendeten Dateinamen
$ python sample.py -s
usage: sample.py [-h] [-d DIR] [-f FILE]
sample.py: error: unrecognized arguments: -s
Für Bash erfolgt das Debuggen auf sehr primitive Weise. Im Allgemeinen üben Sie wahrscheinlich das Debuggen von Skripten mit den folgenden Optionen:
Möglichkeit | Erläuterung |
---|---|
-u | Wenn es eine undefinierte Variable gibt, endet der Prozess. |
-v | Zeigen Sie den Inhalt des Skripts in der Reihenfolge der Ausführung an. Der Variablenname wird unverändert angezeigt. |
-x | Zeigen Sie den Inhalt des Skripts in der Reihenfolge der Ausführung an. Variablen können erweitert werden, um Debug-Informationen anzuzeigen |
Geben Sie Shebang als Verwendung die obige Option (Beispiel: "#! / Bin / bash -x"), Fügen Sie "set -x" ein, wo Sie das Skript-Debugging starten möchten, und "set + x", wo Sie es beenden möchten. Die Option -x zeigt einen Nullbefehl (:) an, sodass Sie Kommentare einfügen können, die nur während des Debuggens sichtbar sind.
Das Beispielskript und das Ausführungsergebnis sind unten aufgeführt.
sample.sh
#!/bin/bash -x
START="Skript starten"
END="Ende des Skripts"
echo ${START} #Die Variable wird im erweiterten Zustand angezeigt
set +x #Optionen abbrechen
:Dieser Nullbefehl wird nicht angezeigt
echo "Dieser Echo-Befehl gibt nur den Zeichenfolgenteil aus"
set -x #Optionsaktivierung
:Dieser Nullbefehl wird angezeigt
echo "${END}"
Ausführungsergebnis.
$ ./sample.sh
+ START=Skript starten
+ END=Ende des Skripts
+Echo-Skript starten
Skript starten
+ set +x
Dieser Echo-Befehl gibt nur den Zeichenfolgenteil aus
+ :Dieser Nullbefehl wird angezeigt
+Echo-Skript beenden
Ende des Skripts
Für Python3 ist das Debuggen mit dem Debugger pdb möglich. Fügen Sie zur Verwendung "import pdb; pdb.set_trace ()" ein, wo Sie und debuggen möchten Der Debugger startet, wenn das Skript die obige Einfügeposition erreicht.
Da ich pdb selbst nicht benutze, werde ich einen Artikel schreiben, auf den ich mich dieses Mal bezog (ich werde ihn in Zukunft hinzufügen). ・ "Pdb - Python Debugger" ・ "Python-Debug-Tipps (@TakesxiSximada)" ・ "Einführung in die effiziente Debuck-Methode in Python"
Es ist ein sehr grundlegender Inhalt, aber weil es "Gegenstände gab, deren Untersuchung länger dauerte als erwartet". Ich werde es als Memorandum belassen.
In Bezug auf das Ersetzen von Bash durch Python ・ "Was entspricht der Bash-Falle (Signalerkennung)?" ・ "Welche Python-Funktion entspricht in erster Linie grundlegenden Befehlen wie cd / pwd / mkdir?" ・ "Ist es einfacher, Dateien mit sed oder awk zu verarbeiten, oder sollte ich Python verwenden?" Und es gibt kein Ende für das, wonach man suchen muss. Später werde ich diesen Inhalt auf Qiita veröffentlichen.
Python 3.x anstelle von Bash. Es ist ein halbes Jahr her, seit ich auf diese Idee gekommen bin. In den letzten sechs Monaten habe ich nur einmal schmerzhafte Erfahrungen mit Python gemacht. Das von mir erstellte Python 3 hat nicht funktioniert.
Migrieren Sie Python-Skripte aus der Entwicklungsumgebung (Debian 8.8) in eine andere Verifizierungsumgebung (CentOS 7.x). Als ich versuchte, es unter CentOS auszuführen, funktionierte das Skript nicht. Der Grund dafür ist, dass CentOS 7.x standardmäßig 2.7 verwendet. Da es sich um eine Überprüfungsumgebung handelt, ist es außerdem nicht möglich, ein neues Paket (Python3) zu installieren. Weinen Wir haben Python so umgeschrieben, dass es von 3.x auf 2.7 funktioniert.
Aus dieser Erfahrung habe ich das Wissen gewonnen, dass "nach Überprüfung der Ausführungsumgebung das Skript geschrieben wird". Es ist wichtig, Runtime.
Recommended Posts