Cet article résume le savoir-faire pour remplacer les scripts Bash par des scripts Python, mais nous prévoyons d'apporter des corrections à l'avenir.
Utilisez la fonction print
. C'est un argument de longueur variable, et si vous en donnez plus d'un, il sera sorti séparé par un espace par défaut.
Bash
echo Hello, world!
↓
Python3.5
print("Hello,", "world!")
Si vous souhaitez afficher une sortie autre que la sortie standard, spécifiez-la sous la forme fichier = ○○
. Par exemple, dans le cas d'une erreur standard:
Bash
echo Error >&2
↓
Python3.5
import sys
print("Error", file=sys.stderr)
Pour écraser ou ajouter à un fichier, utilisez ce qui suit.
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)
L'espace entre les arguments affichés et le caractère de saut de ligne à la fin de la ligne peut être remplacé par un autre caractère. Par exemple, pour définir le délimiteur sur tabulation et le caractère à la fin de la ligne sur aucun:
Python3.5
print("foo", "bar", sep="\t", end="")
Dans Bash etc., c'est une analyse d'options difficile, mais en Python, elle peut être facilement analysée avec le module ʻargparse`. En gros, utilisez-le comme suit.
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)
Chaque option est accessible avec ʻargs.verbose, ʻargs.quiet
, etc.
Voir le commentaire officiel pour plus de détails. https://docs.python.jp/3/library/argparse.html
Vous pouvez utiliser subprocess.run
depuis Python 3.5. Utilisez ceci si vous ne pensez pas à la compatibilité avec les versions antérieures.
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"])
En plus de la liste, iterable est OK. (Taple etc.)
Spécifiez check = True
. L'exception est subprocess.CalledProcessError
.
Python3.5
import subprocess
subprocess.run(["git", "push"], check=True)
Spécifiez stdout = subprocess.PIPE
・ stderr = subprocess.PIPE
. Il peut être récupéré avec les attributs «stdout» et «stderr» de la valeur de retour, respectivement. Veuillez noter que c'est un type «octet».
Python3
import subprocess
result = subprocess.run(["apt", "list", "--upgradable"], stderr=subprocess.PIPE, stdout=subprocess.PIPE, check=True)
process(result.stdout)
Spécifiez subprocess.DEVNULL
au lieu de subprocess.PIPE
.
Ajoutez ʻinput = à l'argument de
subprocess.run`. Veuillez spécifier par type d'octet.
Python3.5
import subprocess
assert subprocess.run(["cat"], input=b"aaa\n", stdout=subprocess.PIPE).stdout == b"aaa\n"
Spécifiez l'objet fichier ouvert par la fonction ʻopen, etc. dans chaque argument de
stdin (pas ʻinput
), stdout
et stderr
de subprocess.run
. Tant que l'entrée et la sortie sont des données texte, le deuxième argument de ʻopen peut être sans
b`, mais il est préférable de l'avoir.
PS: Il est plus facile d'utiliser pathlib
.
from pathlib import Path
python_path = Path("/usr/bin/python3")
Ce qui suit présente une méthode héritée qui n'utilise pas pathlib
.
Vous pouvez l'obtenir avec ʻos.getcwd () . Ou, lorsque vous utilisez
pathlib, vous pouvez l'obtenir avec
Path ()(chemin relatif),
Path.cwd () ʻou Path (). Resolve ()
(chemin absolu).
Utilisez ʻos.chdir`.
Bash
cd directory
↓
Python3.5
import os
os.chdir("directory")
Utilisez ʻos.listdir`. Aucun argument n'est requis pour afficher le contenu du répertoire courant.
Bash
foo=$(ls)
↓
Python3.5
import os
foo = os.listdir()
Si vous voulez voir le contenu d'un répertoire particulier, indiquez ce chemin.
Bash
foo=$(ls bar)
↓
Python3.5
import os
foo = os.listdir("bar")
Pour utiliser pathlib.Path
, utilisez la méthode ʻiterdir (). Puisqu'il s'agit d'un générateur qui est retourné, utilisez une boucle for ou listez-le avec
list ()`.
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)
Si vous souhaitez utiliser la correspondance de modèle, utilisez à la place glob.glob
ou glob.iglob
. Le premier retourne une liste et le second retourne un itérateur, donc le dernier doit être utilisé pour passer aux instructions for
, map
, filter
, etc.
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)
Si vous utilisez pathlib.Path
, utilisez la méthode glob
.
Python3.5+pathlib
from pathlib import Path
for tmp_file in Path().glob("*.tmp"):
tmp_file.unlink()
Si vous voulez créer un seul répertoire, utilisez ʻos.mkdir`.
Bash
mkdir test_dir
↓
Python3.5
import os
os.mkdir("test_dir")
Pour pathlib.Path
, utilisez la méthode mkdir
.
Python3.5+pathlib
from pathlib import Path
Path("test_dir").mkdir()
Utilisez mode
si vous voulez limiter les permissions au-delà des valeurs par défaut (777 & umask values).
Bash
mkdir -m 700 secret_dir
↓
Python3.5
import os
os.mkdir("secret_dir", mode=0o700)
Notez que si vous essayez de créer un répertoire avec cette fonction mais qu'il existe déjà, l'exception FileExitsError
sera levée. Cet argument peut également être utilisé avec la méthode pathlib.Path.mkdir
.
Utilisez ʻos.makedirs si vous voulez créer des répertoires de manière récursive. Si cela ne vous dérange pas que le répertoire existe déjà, utilisez l'option ʻexist_ok
. Vous pouvez également utiliser l'option mode ainsi que ʻos.mkdir`.
Bash
mkdir -p /usr/local/my_software
↓
Python3.5
import os
os.makedirs("/usr/local/my_software", exist_ok=True)
Si ʻexist_ok = True n'est pas spécifié et que le répertoire existe déjà, l'exception ʻOSError
sera lancée. Pour pathlib, utilisez l'option parents
de la méthode 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))
Si vous passez une instance de la classe Path
en tant qu'argument, vous pouvez la passer telle quelle s'il s'agit de Python 3.6 ou supérieur. Dans le cas de 3.5, utilisez str
pour le convertir en chaîne de caractères.
Utilisez ʻos.chmod`.
Bash
chmod 700 directory
↓
Python3.5
import os
os.chmod("directory", 0o700)
La classe Path
a également une méthode avec le même nom.
Python3.5+pathlib
from pathlib import Path
Path("directory").chmod(0o700)
De plus, lors de la spécification au format original de permission + α, comme lors de l'affectation de bits d'exécution, utilisez-le avec l'opération ʻos.stat` / bit.
Bash
chmod +x script.sh
↓
Python3.5
import os
os.chmod("script.sh", os.stat("script.sh").st_mode | 0o111)
Pour la classe Path, utilisez la méthode stat
au lieu de ʻos.stat`.
Python3.5+pathlib
from pathlib import Path
script_path = Path("script.sh")
script_path.chmod(script_path.stat().st_mode | 0o111)
Utilisez ʻos.getuid () et ʻos.getgid ()
pour obtenir respectivement l'UID et le GID de l'utilisateur actuel.
Python3.5
import os, sys
if os.getuid() != 0:
print("Exécutez ce script en tant que root", file=sys.stderr)
exit(1)
Utilisez également pwd.getpwnam
et grp.getgrnam
pour obtenir respectivement l'UID et le GID de groupe de l'utilisateur avec le nom spécifié. Les attributs pw_uid
et gr_gid
de chaque valeur de retour sont respectivement l'UID et le GID. S'il n'y a pas de groupe d'utilisateurs avec le nom spécifié, l'exception KeyError
sera renvoyée, alors attrapez-la comme il convient.
Python3.5
import grp
import pwd
assert pwd.getpwnam("root").pw_uid == 0
assert grp.getgrnam("root").gr_gid == 0
Utilisez la commande shutil.chown
.
Bash
chown root:www /var/www/html
↓
Python3.5
import shutil
shutil.chown("/var/www/html", "root", "www")
Remarque: ces fonctions ne sont pas implémentées sous Windows. De plus, les modules pwd
et grp
ne sont pas disponibles depuis Windows.
Utilisez shutil.copy
pour copier le fichier normalement. Utilisez-le de la même manière que la commande cp
.
import shutil
shutil.copy("old.txt", "new.txt")
shutil.copy("old.txt", "directory")
Si vous souhaitez également copier les métadonnées, utilisez shutil.copy2
. L'utilisation est la même que celle de «copier». Utilisez shutil.copyfileobj
si vous souhaitez copier des objets fichier les uns sur les autres.
import shutil
with open("old.txt", "rb") as old:
with open("new.txt", "wb") as new:
shutil.copyfileobj(old, new)
Si vous voulez copier le répertoire, utilisez shutil.copytree
.
Utilisez shutil.move
. Il y a aussi ʻos.rename`, mais c'est uniquement pour les fichiers.
Utilisez ʻos.remove` pour supprimer le fichier.
Bash
rm file
↓
Python3.5
import os
from pathlib import Path
os.remove("file") # or Path("file").unlink()
Pour supprimer un répertoire vide, utilisez ʻos.rmdir ou la méthode ʻunlink
de la classe Path
. Utilisez shutil.rmtree
pour supprimer récursivement tout le répertoire non vide.
Bash
rm -rf /
↓
Python3.5
import shutil
shutil.rmtree("/")
Il peut être créé avec la méthode symlink_to
de la classe ʻos.symlink ou
Path`.
Bash
ln -s foo bar
↓
Python3.5
import os
os.symlink("foo", "bar") # or Path("bar").symlink_to("foo")
C'est une bonne idée d'utiliser le package requests
.
Si vous souhaitez obtenir le contenu du fichier et l'analyser directement avec Python ultérieurement, écrivez comme suit.
import requests
req = requests.get("http://server/page.html")
html = req.text
Si vous souhaitez télécharger un fichier volumineux, écrivez:
import requests
import posixpath
import os
import shutil
req = requests.get("http://server/largefile.deb", stream=True)
with open(os.path.join("~/Télécharger",posixpath.basename(req.url)), "wb") as f:
shutil.copyfileobj(req.raw, f)
Si vous ne pouvez pas utiliser tous les paquets, utilisez plutôt le module ʻ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")
Utilisez ʻos.access` pour vérifier les permissions de l'utilisateur actuel.
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))
L'horodatage de la date de mise à jour peut être obtenu avec l'attribut st_mtime
du taple nommé qui peut être obtenu avec le ʻos.stat ou la méthode
stat de la classe
Path`.
La taille du fichier peut également être obtenue avec l'attribut st_size
de la valeur de retour de la méthode stat
de la classe ʻos.stat ou de la classe
Path`. Notez que dans le cas d'un répertoire, ce n'est pas la taille totale des fichiers qu'il contient.
Utilisez shutil.unpack_archive
pour décompresser. C'est le plus simple pour diverses archives tar et zips.
Bash
tar xf foo.tar.xz
↓
Python
import shutil
shutil.unpack_archive("foo.tar.xz")
Vous pouvez spécifier la destination de décompression avec le deuxième argument de cette fonction.
Bash
tar xf foo.tar.gz -C bar
↓
Python
import shutil
shutil.unpack_archive("foo.tar.gz", "bar")
Utilisez shutil.make_archive
si vous voulez compresser un répertoire entier. Par exemple, si vous voulez compresser le répertoire nommé bar
et créer une archive nommée foo.tar.xz
, écrivez comme suit.
Bash
tar cf foo.tar.xz bar
↓
Python
import shutil
shutil.make_archive("foo", "xztar", base_dir="bar")
Ces fichiers peuvent être lus et écrits comme des fichiers ordinaires en utilisant respectivement les modules «gzip», «bz2» et «lzma».
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
Utilisez le module tarfile
. Utilisez ʻextractall () `pour la décompression. Par exemple, utilisez-le comme suit.
import tarfile
with tarfile.open("tarfile.tar.xz") as f:
f.extractall()
Si vous spécifiez un répertoire dans le premier argument, il y sera développé. Obtenez la liste des fichiers tar avec membres ()
. (La liste sera retournée)
Utilisez ʻadd () lors de la création d'un fichier tar, mais faites attention au mode de fichier spécifié par ʻopen ()
. Seul «w» est considéré comme non compressé. Par exemple, si vous souhaitez créer une archive au format tar.xz, écrivez comme suit.
import tarfile
with tarfile.open("archive.tar.xz", "w:xz") as f:
f.add("directory")
Ajoutez : (nom du format compressé)
après w
comme ceci.
zip
Utilisez zipfile.ZipFile
. (http://docs.python.jp/3.6/library/zipfile.html#zipfile-objects)
Par exemple, si vous souhaitez extraire tout le contenu du fichier ZIP dans le répertoire actuel, écrivez comme suit.
import zipfile
with zipfile.ZipFile("foo.zip") as ar:
ar.extractall()
Puisqu'il y a un problème d'encodage de nom de fichier avec les fichiers zip, vous pouvez appeler les commandes du système d'exploitation zip
/ ʻunzip avec
subprocess.run`. (Remix japonais Windows / Ubuntu)
Le répertoire de fichiers temporaires utilise le module tempfile
.
Utilisez tempfile.TemporaryFile
si vous ne souhaitez pas utiliser le fichier en externe.
import tempfile
with tempfile.TemporaryFile() as temp_file_handler:
temp_file_handler.write(some_byte_array)
# ...
some_bytes = temp_file_handler.read(length)
# ...
Pour un usage externe, utilisez tempfile.NamedTemporaryFile
. Il existe un attribut name
, qui vous permet d'obtenir le nom du fichier.
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)
# ...
Si vous souhaitez spécifier l'extension / le préfixe, utilisez suffix
/ prefix
. Par exemple, le code suivant
import tempfile
with tempfile.NamedTemporaryFile(prefix="tempfile-", suffix=".deb") as temp_file:
print(temp_file.name)
Imprime une chaîne comme / tmp / tempfile-hz1u73cr.deb
et quitte.
Dans les deux cas, le fichier sera supprimé lorsque l'instruction with
est quittée. De plus, le mode d'ouverture par défaut pour les fichiers est w + b
, ou mode binaire.
Le répertoire temporaire est créé avec tempfile.TemporaryDirectory
. Normalement, vous utiliseriez l'instruction with
comme suit:
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)
Dans ce cas, si vous quittez l'instruction with
, le répertoire temporaire et les fichiers qu'il contient seront supprimés. De plus, dans cet exemple, le type de «temp_dir_name» est «str».
Vous pouvez l'obtenir et le définir dans un dictionnaire (comme) nommé ʻos.environ`.
Python3.5
import os
print("256 couleurs" if "TERM" in os.environ and "256color" in os.environ["TERM"] else "16 couleurs")
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"])
Si vous souhaitez incorporer des variables d'environnement dans une chaîne, utilisez ʻ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
#Tout chemin("/bin/bash")rends le
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
Différents délimiteurs peuvent être obtenus avec ʻos.sep (répertoire), ʻos.extsep
(extension) et ʻos.pathsep` (variable d'environnement PATH).
Python3.5
import os
print(os.sep, os.extsep, os.pathsep)
# Windows: \ . ;
#autre que ça: / . :
Utilisez ʻos.path.join` pour joindre les chemins.
Python3.5
import os
os.makedirs(os.path.join(PROJECT_ROOT, "build"), exist_ok=True)
Utilisez ʻos.path.split, ʻos.path.basename
, ʻos.path.dirname` pour diviser le chemin en basename et dirname.
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)
Utilisez ʻos.path.splitext` pour extraire la partie extension / non-extension du chemin.
Python3.5
import os
root, ext = os.path.splitext("/etc/nginx/nginx.conf")
print(root, ext)
# /etc/nginx/nginx .conf
Utilisez ʻos.path.expanduserpour gérer les chemins qui utilisent
~` pour représenter votre répertoire personnel.
Bash
echo "Your home directory is: $HOME"
↓
Python3.5
import os
print("Your home directory is:", os.path.expanduser("~"))
Si vous êtes conscient de la compatibilité avec Windows, utilisez-le uniquement pour obtenir le répertoire personnel comme celui-ci, et utilisez ʻos.path.join` ensemble.
Utilisez également ʻos.path.expandvars` pour travailler avec des chemins qui incluent des variables d'environnement.
Python3.5
import os
os.makedirs(os.path.join(PROJECT_ROOT, "build", os.path.expandvars("python-$PYTHON_VERSION")), exist_ok=True)
Il existe également un moyen d'utiliser pathlib
, mais je ne l'expliquerai pas pour le moment.
https://docs.python.jp/3/library/pathlib.html
De plus, je prévois d'écrire quelque chose d'équivalent à sed
・ ʻawk ・
grep`
http://qiita.com/supersaiakujin/items/12451cd2b8315fe7d054
Recommended Posts