Dieser Artikel fasst das Know-how zum Ersetzen von Bash-Skripten durch Python-Skripte zusammen. Wir planen jedoch, in Zukunft Korrekturen vorzunehmen.
Verwenden Sie die Funktion "Drucken". Dies ist ein Argument mit variabler Länge. Wenn Sie mehr als ein Argument angeben, wird es standardmäßig durch ein Leerzeichen getrennt ausgegeben.
Bash
echo Hello, world!
↓
Python3.5
print("Hello,", "world!")
Wenn Sie eine andere als die Standardausgabe ausgeben möchten, geben Sie diese in Form von file = ○○
an. Zum Beispiel im Fall eines Standardfehlers:
Bash
echo Error >&2
↓
Python3.5
import sys
print("Error", file=sys.stderr)
Verwenden Sie Folgendes, um eine Datei zu überschreiben oder zu ergänzen.
Bash
echo foo > file1.txt
echo bar >> file1.txt
echo hoge >> file2.txt
echo fuga >> file2.txt
↓
Python3.5
with open("file1.txt", "w") as f:
print("foo", file=f)
print("bar", file=f)
with open("file2.txt", "a") as f:
print("hoge", file=f)
print("fuga", file=f)
Der Abstand zwischen den angezeigten Argumenten und dem Zeilenvorschubzeichen am Zeilenende kann in ein anderes Zeichen geändert werden. So setzen Sie beispielsweise das Trennzeichen auf tab und das Zeichen am Ende der Zeile auf none:
Python3.5
print("foo", "bar", sep="\t", end="")
In Bash usw. ist es eine schwierige Optionsanalyse, aber in Python kann sie einfach mit dem argparse
-Modul analysiert werden. Verwenden Sie es grundsätzlich wie folgt.
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("--verbose", "-v", help="Verbose", action="store_true")
parser.add_argument("--quiet", "-q", help="Suppress messages", action="store_true")
parser.add_argument("target", help="target")
parser.add_argument("source", nargs="+", help="source")
args = parser.parse_args()
function(args.option)
Auf jede Option kann mit args.verbose
, args.quiet
usw. zugegriffen werden.
Einzelheiten finden Sie im offiziellen Kommentar. https://docs.python.jp/3/library/argparse.html
Sie können subprocess.run
aus Python 3.5 verwenden. Verwenden Sie diese Option, wenn Sie nicht an die Kompatibilität mit früheren Versionen denken.
Bash
g++ sample.cpp -o sample -std=gnu++14 -march=native -O3
↓
Python3.5
import subprocess
subprocess.run(["g++", "sample.cpp", "-o", "sample", "-std=gnu++14", "-march=native", "-O3"])
Zusätzlich zur Liste ist iterable OK. (Taple etc.)
Geben Sie "check = True" an. Die Ausnahme ist "subprocess.CalledProcessError".
Python3.5
import subprocess
subprocess.run(["git", "push"], check=True)
Geben Sie stdout = subprocess.PIPE
st stderr = subprocess.PIPE
an. Es kann mit den Attributen "stdout" und "stderr" des Rückgabewerts abgerufen werden. Bitte beachten Sie, dass es sich um einen Byte-Typ handelt.
Python3
import subprocess
result = subprocess.run(["apt", "list", "--upgradable"], stderr=subprocess.PIPE, stdout=subprocess.PIPE, check=True)
process(result.stdout)
Geben Sie "subprocess.DEVNULL" anstelle von "subprocess.PIPE" an.
Fügen Sie dem Argument von "subprocess.run" "input =" hinzu. Bitte geben Sie den Bytetyp an.
Python3.5
import subprocess
assert subprocess.run(["cat"], input=b"aaa\n", stdout=subprocess.PIPE).stdout == b"aaa\n"
Geben Sie das durch die Funktion "Öffnen" usw. geöffnete Dateiobjekt in jedem Argument von "stdin" (nicht "Eingabe"), "stdout" und "stderr" von "subprocess.run" an. Solange die Eingabe und Ausgabe Textdaten sind, kann das zweite Argument von "offen" ohne "b" sein, aber es ist besser, es zu haben.
PS: Es ist einfacher, "pathlib" zu verwenden.
from pathlib import Path
python_path = Path("/usr/bin/python3")
Im Folgenden wird eine Legacy-Methode vorgestellt, die kein "pathlib" verwendet.
Sie können es mit os.getcwd ()
erhalten. Wenn Sie "pathlib" verwenden, können Sie es auch mit "Path ()" (relativer Pfad), "Path.cwd ()" oder "Path (). Resolve ()" (absoluter Pfad) abrufen.
Verwenden Sie os.chdir
.
Bash
cd directory
↓
Python3.5
import os
os.chdir("directory")
Verwenden Sie os.listdir
. Es ist kein Argument erforderlich, um den Inhalt des aktuellen Verzeichnisses anzuzeigen.
Bash
foo=$(ls)
↓
Python3.5
import os
foo = os.listdir()
Wenn Sie den Inhalt eines bestimmten Verzeichnisses anzeigen möchten, geben Sie diesen Pfad an.
Bash
foo=$(ls bar)
↓
Python3.5
import os
foo = os.listdir("bar")
Um pathlib.Path
zu verwenden, verwenden Sie die Methode iterdir ()
. Da es sich um einen zurückgegebenen Generator handelt, verwenden Sie eine for-Schleife oder listen Sie sie mit list ()
auf.
Python3.5+pathlib
from pathlib import Path
foo = Path().iterdir() # foo=$(ls)
bar = Path("baz").iterdir() # bar=$(ls baz)
# ls qux
for path in Path("qux").iterdir():
print(path)
Wenn Sie den Mustervergleich verwenden möchten, verwenden Sie stattdessen "glob.glob" oder "glob.iglob". Ersteres gibt eine Liste zurück und letzteres gibt einen Iterator zurück, daher sollte letzteres verwendet werden, um an "for" -Anweisungen, "map", "filter" usw. zu übergeben.
Bash
audio_files=$(ls *.wav)
ls *.tmp | xargs rm -f
↓
Python3.5
import glob
import os
audio_files = glob.glob("*.wav")
for tmp_file in glob.iglob("*.tmp"):
os.remove(tmp_file)
Wenn Sie pathlib.Path
verwenden, verwenden Sie die Methode glob
.
Python3.5+pathlib
from pathlib import Path
for tmp_file in Path().glob("*.tmp"):
tmp_file.unlink()
Wenn Sie ein einzelnes Verzeichnis erstellen möchten, verwenden Sie "os.mkdir".
Bash
mkdir test_dir
↓
Python3.5
import os
os.mkdir("test_dir")
Verwenden Sie für pathlib.Path
die Methode mkdir
.
Python3.5+pathlib
from pathlib import Path
Path("test_dir").mkdir()
Verwenden Sie "mode", wenn Sie die Berechtigungen über die Standardwerte (777 & umask-Werte) hinaus einschränken möchten.
Bash
mkdir -m 700 secret_dir
↓
Python3.5
import os
os.mkdir("secret_dir", mode=0o700)
Beachten Sie, dass die Ausnahme "FileExitsError" ausgelöst wird, wenn Sie versuchen, ein Verzeichnis mit dieser Funktion zu erstellen, das jedoch bereits vorhanden ist. Dieses Argument kann auch mit der Methode pathlib.Path.mkdir
verwendet werden.
Verwenden Sie os.makedirs
, wenn Sie Verzeichnisse rekursiv erstellen möchten. Wenn Sie nichts dagegen haben, dass das Verzeichnis bereits vorhanden ist, verwenden Sie die Option "exist_ok". Sie können die Modusoption auch wie bei os.mkdir
verwenden.
Bash
mkdir -p /usr/local/my_software
↓
Python3.5
import os
os.makedirs("/usr/local/my_software", exist_ok=True)
Wenn Sie nicht "exist_ok = True" angeben und das Verzeichnis bereits vorhanden ist, wird die Ausnahme "OSError" ausgelöst. Verwenden Sie für pathlib die Option "Eltern" der Methode "mkdir".
Python3.5+pathlib
from pathlib import Path
Path("/usr/local/my_software").mkdir(parents=True, exist_ok=True)
Bash
find . -type d -exec chmod 700 {} \;
find . -type f -exec chmod 600 {} \;
↓
Python
import os
for root, dirs, files in os.walk("."):
for dir in dirs:
os.chmod(0o700, os.path.join(root,dir))
for file in files:
os.chmod(0o600, os.path.join(root, file))
Wenn Sie eine Instanz der Klasse "Path" als Argument übergeben, können Sie sie so übergeben, wie sie ist, wenn es sich um Python 3.6 oder höher handelt. Verwenden Sie im Fall von 3.5 "str", um es in eine Zeichenfolge zu konvertieren.
Verwenden Sie os.chmod
.
Bash
chmod 700 directory
↓
Python3.5
import os
os.chmod("directory", 0o700)
Die Path
Klasse hat auch eine Methode mit dem gleichen Namen.
Python3.5+pathlib
from pathlib import Path
Path("directory").chmod(0o700)
Wenn Sie im ursprünglichen Berechtigungsformat + α angeben, z. B. wenn Sie Ausführungsbits zuweisen, verwenden Sie diese zusammen mit der Operation "os.stat" / bit.
Bash
chmod +x script.sh
↓
Python3.5
import os
os.chmod("script.sh", os.stat("script.sh").st_mode | 0o111)
Verwenden Sie für die Path-Klasse die stat
-Methode anstelle von os.stat
.
Python3.5+pathlib
from pathlib import Path
script_path = Path("script.sh")
script_path.chmod(script_path.stat().st_mode | 0o111)
Verwenden Sie "os.getuid ()" und "os.getgid ()", um die UID bzw. GID des aktuellen Benutzers abzurufen.
Python3.5
import os, sys
if os.getuid() != 0:
print("Führen Sie dieses Skript als root aus", file=sys.stderr)
exit(1)
Verwenden Sie außerdem "pwd.getpwnam" und "grp.getgrnam", um die UID und die Gruppen-GID des Benutzers mit dem angegebenen Namen abzurufen. Die Attribute "pw_uid" und "gr_gid" jedes Rückgabewerts sind die UID bzw. die GID. Wenn es keine Benutzergruppe mit dem angegebenen Namen gibt, wird die Ausnahme "KeyError" zurückgegeben. Fangen Sie sie daher entsprechend ab.
Python3.5
import grp
import pwd
assert pwd.getpwnam("root").pw_uid == 0
assert grp.getgrnam("root").gr_gid == 0
Verwenden Sie den Befehl shutil.chown
.
Bash
chown root:www /var/www/html
↓
Python3.5
import shutil
shutil.chown("/var/www/html", "root", "www")
Hinweis: Diese Funktionen sind in Windows nicht implementiert. Außerdem sind die Module "pwd" und "grp" unter Windows nicht verfügbar.
Verwenden Sie shutil.copy
, um die Datei normal zu kopieren. Verwenden Sie es auf die gleiche Weise wie den Befehl cp
.
import shutil
shutil.copy("old.txt", "new.txt")
shutil.copy("old.txt", "directory")
Wenn Sie auch die Metadaten kopieren möchten, verwenden Sie "shutil.copy2". Die Verwendung ist die gleiche wie "Kopie". Verwenden Sie shutil.copyfileobj
, wenn Sie Dateiobjekte ineinander kopieren möchten.
import shutil
with open("old.txt", "rb") as old:
with open("new.txt", "wb") as new:
shutil.copyfileobj(old, new)
Wenn Sie das Verzeichnis kopieren möchten, verwenden Sie "shutil.copytree".
Verwenden Sie shutil.move
. Es gibt auch "os.rename", aber es ist nur für Dateien.
Verwenden Sie os.remove
, um die Datei zu entfernen.
Bash
rm file
↓
Python3.5
import os
from pathlib import Path
os.remove("file") # or Path("file").unlink()
Verwenden Sie zum Entfernen eines leeren Verzeichnisses die Methode unlink
der Klasse os.rmdir
oder Path
. Verwenden Sie shutil.rmtree
, um das gesamte nicht leere Verzeichnis rekursiv zu löschen.
Bash
rm -rf /
↓
Python3.5
import shutil
shutil.rmtree("/")
Es kann mit der Methode "symlink_to" der Klasse "os.symlink" oder "Path" erstellt werden.
Bash
ln -s foo bar
↓
Python3.5
import os
os.symlink("foo", "bar") # or Path("bar").symlink_to("foo")
Es ist eine gute Idee, das "Anfragen" -Paket zu verwenden. Wenn Sie den Inhalt der Datei abrufen und später direkt mit Python analysieren möchten, schreiben Sie wie folgt.
import requests
req = requests.get("http://server/page.html")
html = req.text
Wenn Sie eine große Datei herunterladen möchten, schreiben Sie:
import requests
import posixpath
import os
import shutil
req = requests.get("http://server/largefile.deb", stream=True)
with open(os.path.join("~/herunterladen",posixpath.basename(req.url)), "wb") as f:
shutil.copyfileobj(req.raw, f)
Wenn Sie nicht alle Pakete verwenden können, verwenden Sie stattdessen das Modul "urllib.request" (https://docs.python.jp/3/library/urllib.request.html).
test
Bash
[[ -e "file.txt" ]] && echo "Exist" || echo "Not exist"
↓
Python3.5
import os
print("Exist" if os.path.exists("file.txt") else "Not exist")
Python3.5+pathlib
from pathlib import Path
print("Exist" if Path("file.txt").exists() else "Not exist")
Bash
[[ -f "file.txt" ]] && echo "File" || echo "Not file"
[[ -d "directory" ]] && echo "Directory" || echo "Not directory"
↓
Python3.5
import os
print("File" if os.path.isfile("file.txt") else "Not file")
print("Directory" if os.path.isdir("directory") else "Not directory")
Python3.5+pathlib
from pathlib import Path
print("File" if Path("file.txt").is_file() else "Not file")
print("Directory" if Path("directory").is_dir() else "Not directory")
Verwenden Sie os.access
, um die Berechtigungen für den aktuellen Benutzer zu überprüfen.
Bash
[[ -r 'file.txt' ]] && echo 'True' || echo 'False'
[[ -r 'file.txt' -a -w 'file.txt' ]] && echo 'True' || echo 'False'
[[ -r 'directory' -a -x 'directory' ]] && echo 'True' || echo 'False'
↓
Python3.5
import os
print(os.access("file.txt", os.R_OK))
print(os.access("file2.txt", os.R_OK | os.W_OK))
print(os.access("directory", os.R_OK | os.X_OK))
Der Aktualisierungsdatum-Zeitstempel kann mit dem Attribut "st_mtime" des benannten Taples erhalten werden, das mit dem Attribut "os.stat" oder der Methode "stat" der Klasse "Path" erhalten werden kann.
Die Dateigröße kann auch mit dem Attribut "st_size" des Rückgabewerts der Methode "stat" der Klasse "os.stat" oder "Path" ermittelt werden. Beachten Sie, dass es sich bei einem Verzeichnis nicht um die Gesamtgröße der darin enthaltenen Dateien handelt.
Verwenden Sie shutil.unpack_archive
zum Dekomprimieren. Dies ist am einfachsten für verschiedene Tarballs und Reißverschlüsse.
Bash
tar xf foo.tar.xz
↓
Python
import shutil
shutil.unpack_archive("foo.tar.xz")
Sie können das Dekomprimierungsziel mit dem zweiten Argument dieser Funktion angeben.
Bash
tar xf foo.tar.gz -C bar
↓
Python
import shutil
shutil.unpack_archive("foo.tar.gz", "bar")
Verwenden Sie "shutil.make_archive", wenn Sie ein gesamtes Verzeichnis komprimieren möchten. Wenn Sie beispielsweise das Verzeichnis "bar" komprimieren und ein Archiv mit dem Namen "foo.tar.xz" erstellen möchten, schreiben Sie wie folgt.
Bash
tar cf foo.tar.xz bar
↓
Python
import shutil
shutil.make_archive("foo", "xztar", base_dir="bar")
Diese Dateien können wie normale Dateien mit den Modulen "gzip", "bz2" und "lzma" gelesen und geschrieben werden.
import gzip
import bz2
import lzma
import shutil
with gzip.open("file.gz", "rb") as gz:
with bz2.open("file.bz2", "wb") as bzip2:
shutil.copyfileobj(gz, bzip2)
with lzma.open("file.xz", "wb") as xz:
shutil.copyfileobj(gz, xz)
tar
Verwenden Sie das Tarfile-Modul. Verwenden Sie extractall ()
zur Dekomprimierung. Verwenden Sie es beispielsweise wie folgt.
import tarfile
with tarfile.open("tarfile.tar.xz") as f:
f.extractall()
Wenn Sie im ersten Argument ein Verzeichnis angeben, wird es dort erweitert. Holen Sie sich die Dateiliste der TAR-Dateien mit "Members ()". (Die Liste wird zurückgegeben)
Verwenden Sie add ()
, um eine TAR-Datei zu erstellen. Achten Sie jedoch auf den durch open ()
angegebenen Dateimodus. Nur "w" wird als unkomprimiert betrachtet. Wenn Sie beispielsweise ein Archiv im Format tar.xz erstellen möchten, schreiben Sie wie folgt.
import tarfile
with tarfile.open("archive.tar.xz", "w:xz") as f:
f.add("directory")
Fügen Sie : (komprimierter Formatname)
nach w
wie folgt hinzu.
zip
Verwenden Sie zipfile.ZipFile
. (http://docs.python.jp/3.6/library/zipfile.html#zipfile-objects)
Wenn Sie beispielsweise den gesamten Inhalt der ZIP-Datei im aktuellen Verzeichnis extrahieren möchten, schreiben Sie wie folgt.
import zipfile
with zipfile.ZipFile("foo.zip") as ar:
ar.extractall()
Da bei ZIP-Dateien ein Problem mit der Dateinamencodierung auftritt, können Sie die OS-Befehle "zip" / "unzip" mit "subprocess.run" aufrufen. (Windows / Ubuntu Japanese Remix)
Das temporäre Dateiverzeichnis verwendet das Modul "tempfile".
Verwenden Sie tempfile.TemporaryFile
, wenn Sie die Datei nicht extern verwenden möchten.
import tempfile
with tempfile.TemporaryFile() as temp_file_handler:
temp_file_handler.write(some_byte_array)
# ...
some_bytes = temp_file_handler.read(length)
# ...
Verwenden Sie für die externe Verwendung tempfile.NamedTemporaryFile
. Es gibt ein Attribut "Name", mit dem Sie den Dateinamen abrufen können.
import tempfile
import subprocess
with tempfile.NamedTemporaryFile() as temp_file:
temp_file.write(some_byte_array)
# ...
subprocess.run(("external-process", temp_file.name), check=True)
# ...
Wenn Sie die Erweiterung / das Präfix angeben möchten, verwenden Sie "Suffix" / "Präfix". Zum Beispiel der folgende Code
import tempfile
with tempfile.NamedTemporaryFile(prefix="tempfile-", suffix=".deb") as temp_file:
print(temp_file.name)
Druckt eine Zeichenfolge wie / tmp / tempfile-hz1u73cr.deb
und wird beendet.
In beiden Fällen wird die Datei gelöscht, wenn die Anweisung "with" beendet wird. Der Standard-Öffnungsmodus für Dateien ist "w + b" oder der Binärmodus.
Das temporäre Verzeichnis wird mit tempfile.TemporaryDirectory
erstellt. Normalerweise würden Sie die Anweisung "with" wie folgt verwenden:
import tempfile
import os
import subprocess
with tempfile.TemporaryDirectory() as temp_dir_name:
temp_conf_name = os.path.join(temp_dir_name, "hoge.conf")
with open(temp_conf_name, "w") as temp_conf:
print("hoge=hogehoge", file=temp_conf)
subprocess.run(("sudo", "hoge", temp_conf_name), check=True)
In diesem Fall werden beim Beenden der Anweisung "with" das temporäre Verzeichnis und die darin enthaltenen Dateien gelöscht. In diesem Beispiel ist der Typ von "temp_dir_name" auch "str".
Sie können es in einem Wörterbuch (wie) mit dem Namen "os.environ" abrufen und einstellen.
Python3.5
import os
print("256 Farben" if "TERM" in os.environ and "256color" in os.environ["TERM"] else "16 Farben")
Python3.5
import os
import pip
if "CUDA_ROOT" not in os.environ:
os.environ["CUDA_ROOT"] = "/usr/local/cuda"
pip.main(["install", "-U", "chainer"])
Wenn Sie Umgebungsvariablen in eine Zeichenfolge einbetten möchten, verwenden Sie "os.path.expandvars".
Python3.5
import os
WORKING_DIR = os.path.join(COMMON_ROOT, os.path.expandvars("work-$USER"))
Python3.5+pathlib
from pathlib import Path
#Alle Pfad("/bin/bash")Gib es zurück
Path("/bin","bash")
Path("/bin") / "bash"
Path("/bin") / Path("bash")
Path("/bin").joinpath("bash")
Path("/bin").joinpath(Path("bash"))
Python3.5+pathlib
from pathlib import Path
p = Path("dir/dir2/file.tar.gz")
print(p.name) # file.tar.gz
print(p.parent) # dir/dir2
print([str(dir) for dir in p.parents]) # ['dir/dir2', 'dir', '.']
print(p.stem) # file.tar
print(p.suffix) # .gz
print(p.suffixes) # ['.tar', '.gz']
Python3.5+pathlib
from pathlib import Path
ico = Path("img/favicon.ico")
gitignore = ico.with_name(".gitignore") # img/.gitignore
png = ico.with_suffix(".png ") # img/favicon.png
Verschiedene Trennzeichen können mit "os.sep" (Verzeichnis), "os.extsep" (Erweiterung) und "os.pathsep" (Umgebungsvariable PATH) erhalten werden.
Python3.5
import os
print(os.sep, os.extsep, os.pathsep)
# Windows: \ . ;
#anders als das: / . :
Verwenden Sie os.path.join
, um die Pfade zu verbinden.
Python3.5
import os
os.makedirs(os.path.join(PROJECT_ROOT, "build"), exist_ok=True)
Verwenden Sie os.path.split
・ os.path.basename
・ os.path.dirname
, um den Pfad in Basisname und Verzeichnisname aufzuteilen.
Python3.5
import os
dirname, basename = os.path.split(FILE_PATH)
assert dirname == os.path.dirname(FILE_PATH)
assert basename == os.path.basename(FILE_PATH)
Verwenden Sie os.path.splitext
, um den Erweiterungsteil / Nichterweiterungsteil des Pfads zu extrahieren.
Python3.5
import os
root, ext = os.path.splitext("/etc/nginx/nginx.conf")
print(root, ext)
# /etc/nginx/nginx .conf
Verwenden Sie os.path.expanduser
, um Pfade zu behandeln, die ~
verwenden, um Ihr Home-Verzeichnis darzustellen.
Bash
echo "Your home directory is: $HOME"
↓
Python3.5
import os
print("Your home directory is:", os.path.expanduser("~"))
Wenn Sie sich der Kompatibilität mit Windows bewusst sind, verwenden Sie es nur, um das Ausgangsverzeichnis wie folgt abzurufen, und verwenden Sie "os.path.join" zusammen.
Verwenden Sie außerdem "os.path.expandvars", um mit Pfaden zu arbeiten, die Umgebungsvariablen enthalten.
Python3.5
import os
os.makedirs(os.path.join(PROJECT_ROOT, "build", os.path.expandvars("python-$PYTHON_VERSION")), exist_ok=True)
Es gibt auch eine Möglichkeit, "pathlib" zu verwenden, aber ich werde es zu diesem Zeitpunkt nicht erklären. https://docs.python.jp/3/library/pathlib.html
Außerdem habe ich vor, etwas zu schreiben, das "sed", "awk" und "grep" entspricht.
http://qiita.com/supersaiakujin/items/12451cd2b8315fe7d054
Recommended Posts