[Pour passer de Bash à Ruby et Python3 J'ai comparé plus de traitement avec Bash <-> Ruby <-> Python3 (introduit sur un autre site). ](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 /)
Cet article décrit ce que j'ai recherché pour remplacer Bash Script par Python 3.x. La motivation pour penser au remplacement était que je pensais que «Bash Script over 300 Steps m'étranglerait».
Je comprends les atouts de Bash. À l'exception de l'environnement embarqué, il est garanti de fonctionner avec les principales distributions et Si vous écrivez avec la compatibilité POSIX à l'esprit, le nombre de corrections au moment du portage sera réduit. Familier de nombreux développeurs avant tout, cela signifie un grand nombre de personnes (membres) qui peuvent modifier le script. Mais en pratique, je n'écris pas Bash étant donné les avantages mentionnés ci-dessus. Parce que je le crée sans y penser, je verrai la douleur à une date ultérieure (exemple: le flux suivant).
Sur la base de cette réalité et des conseils de Google (cité ci-dessous) Nous sommes arrivés à la conclusion que «Python 3.x à partir de 2017».
Original: Source "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.
Traduction Si vous écrivez un script de plus de 100 lignes ou plus, vous devriez probablement l'écrire en Python à la place. Notez que le script grandit. Dans une autre langue pour éviter les corrections fastidieuses par la suite Veuillez réécrire le script dès que possible.
・ Debian 8.6 (64 bits) ・ Bash (GNU bash 4.3.30) ・ Python (Version 3.5.1, Anaconda 4.0.0)
Dans le cas de bash, vous pouvez l'exécuter en écrivant la commande et l'option telles qu'elles sont dans Script, Pour Python, exécutez via le module subprocess.
Voici un exemple d'utilisation d'une commande externe (commande de redimensionnement) (Bash, Python).
sample.sh
#!/bin/bash
resize -s 30 50 #30 caractères par ligne, 50 lignes
sample.py
#!/usr/bin/env python3
-*- coding: utf-8 -*-
import subprocess
#Commandes que vous souhaitez transmettre aux sous-processus+Options de liste
#État, espace compris(run(["resize -s 30 50"]))Erreur si décrit dans
subprocess.run(["resize","-s","30","50"])
Voici un exemple de connexion d'une commande externe et d'un tuyau. Par rapport à la notation "|" de Bash, il y a plus de contenu à décrire.
sample.py
#!/usr/bin/env python3
import subprocess
#Connectez la sortie standard et le tube pour l'erreur standard en spécifiant les deuxième et troisième arguments.
result = subprocess.Popen(["resize","-s","30","50"], \
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = result.communicate() #Obtenir la sortie standard, erreur standard
print("Sortie standard:%s" % out.decode('utf-8')) #Si le traitement de décodage n'est pas effectué, il sera traité comme un octet.
print("Erreur standard:%s" % err.decode('utf-8'))
Voici un exemple d'écriture du résultat de sortie d'une commande externe dans un fichier texte. De plus, le résultat de l'exécution de "python sample.py" est également affiché.
sample.py
#!/usr/bin/env python3
import subprocess
#Fichier journal ouvert(command.log)Débit jusqu'à ce que la sortie standard soit écrite dans
# "communicate()"de[0]部分は、複数de返り値de中から標準出力を受け取るためde記述
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()
#Si vous souhaitez ajouter"a"Ouvrez le fichier en spécifiant.
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;
16 au total
-rw-r--r--1 nao nao 44 24 décembre 19:15 command.log
-rw-r--r--1 nao nao 543 24 décembre 15:58 python_bash.txt
-rwxr-xr-x 1 nao nao 673 24 décembre 19:15 sample.py
-rwxr-xr-x 1 nao nao 77 24 décembre 15:58 sample.sh
Vous aurez la possibilité d'utiliser des documents d'audience lors de la création d'exemples de fichiers et de modèles. Vous trouverez ci-dessous un exemple d'utilisation de la documentation d'audition Bash et Python.
sample.sh
#!/bin/bash
VAR="check"
#Sortie du contenu du document ici.Sortie vers txt.
cat << EOS > output.txt
①
La gamme de documents ici est"<< EOS"La ligne suivant la ligne passée à la commande(①)De
Puis seul"EOS"Une ligne au-dessus de la ligne où(②)Jusqu'à ce que.
La partie EOS peut être une chaîne de caractères libre, mais
La même chaîne doit être utilisée au début et à la fin du document d'audience.
$VAR #Lors de l'utilisation de variables dans entendre des documents.
\$VAR #Lorsqu'il n'est pas généré en tant que variable.
②
EOS
sample.py
#!/usr/bin/env python3
VAR="check"
#À la fin du document ici[1:-1]S'il n'y en a pas, des lignes vides sont incluses avant et après la chaîne de caractères.
heredoc = """
Dans le document d'entendre Python,
Entourez la chaîne de trois guillemets.
Si vous souhaitez développer des variables dans votre document
{VAR}
Je vais le décrire comme tel.
Et la variable dans la chaîne est le format de la fonction()Sera étendu avec.
"""[1:-1].format(**locals()) # **Variables de dictionnaire par spécification{'VAR':"check"}Recevez à.
output = open("output.txt", "w")
output.write(heredoc)
output.close
Voici trois exemples d'acquisition d'entrées utilisateur dans le tableau ci-dessous.
Nombre de caractères à saisir | Echo retour | Enter(Décision)Besoin de | |
---|---|---|---|
Exemple 1 | Sans limites | Oui | nécessaire |
Exemple 2 | Sans limites | Aucun | nécessaire |
Exemple 3 | Une lettre | Aucun | Inutile |
sample.sh
#!/bin/bash
echo -n "Veuillez saisir des caractères:" #option"-n"Supprime les sauts de ligne
read USER_INPUT
echo "${USER_INPUT}"
echo -n "Réception d'entrée sans retour d'écho:"
stty -echo #Écho désactivé
read USER_INPUT
stty echo #Écho de retour activé
echo "${USER_INPUT}"
echo -n "Réception d'entrée d'une lettre. Non Entrée requise:"
read -s -n 1 USER_INPUT #Bash seulement
echo "${USER_INPUT}"
sample.py
#!/usr/bin/env python3
import os
import getch # "pip install getch"Il est nécessaire d'installer avec.
print("Veuillez saisir des caractères:", end="")
user_input = input()
print(user_input)
#En plus des méthodes suivantes, getpass du module getpass()Si tu utilises
#Vous pouvez accepter une entrée sans retour d'écho.
#Cependant, par défaut sur le terminal"Password:"Il sera affiché.
print("Réception d'entrée sans retour d'écho:", end="")
os.system("stty -echo")
user_input = input()
os.system("stty echo")
print(user_input)
print("Réception d'entrée d'une lettre. Non Entrée requise:", end="")
user_input = getch.getch()
print(user_input)
Seules les couleurs du texte du message d'erreur (rouge) et du message d'avertissement (jaune) sont indiquées ci-dessous. Côté bash, il semble qu'une fonction qui peut passer une chaîne de caractères avec un tube au lieu d'un argument soit plus simple à utiliser, Puisqu'il s'agit d'un échantillon, il se présente sous la forme de passer des arguments.
sample.sh
#!/bin/bash
function error_message (){
echo -n -e "\033[31m\c" #Séquence d'échappement pour rendre les lettres rouges
echo "$1"
echo -n -e "\033[m\c" #Restaurer la couleur du texte
}
function warning_message (){
echo -n -e "\033[33m\c" #Séquence d'échappement pour rendre les lettres jaunes
echo "$1"
echo -n -e "\033[m\c" #Restaurer la couleur du texte
}
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")
Voici un exemple de cas où des privilèges d'administrateur sont requis lors de l'exécution d'un script.
sample.sh
#!/bin/bash
#Vérifiez l'UID et l'UID d'exécution,"0"(root)Si tel est le cas, vous disposez des privilèges d'administrateur.
# ":-"Partie${EUID}S'il n'y a pas de valeur dans${UID}Moyens de remplacer la valeur de
if [ ${EUID:-${UID}} = 0 ]; then
echo "Vous disposez de privilèges d'administrateur."
else
echo "Vous avez besoin de privilèges d'administrateur pour exécuter ce script."
fi
sample.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
#Vérifiez si vous disposez des privilèges d'administrateur en obtenant l'UID et l'EUID.
if os.getuid() == 0 and os.geteuid() == 0:
print("Vous disposez de privilèges d'administrateur.")
else:
print("Vous avez besoin de privilèges d'administrateur pour exécuter ce script.")
Pour Bash, utilisez getopts pour interpréter les options. À ce stade, si le script est exécuté à l'aide d'une option non définie, Une déclaration d'erreur s'affichera automatiquement. L'exemple de script et le résultat de l'exécution sont présentés ci-dessous.
sample.sh
#!/bin/bash
#getopts passe un caractère optionnel comme premier argument,
#Cette option(Exemple:"d")Immédiatement après le caractère d'option si prend un argument":"Écrire(Exemple:"d:")。
#Dans l'exemple ci-dessous"d"Quand"f"が引数を必要Quandするオプションです。
while getopts d:f:h OPT
do
case $OPT in
d) DIR_NAME=$OPTARG #Les arguments facultatifs sont stockés dans la variable OPTARG.
;;
f) FILE_NAME=$OPTARG
;;
h) echo "L'utilisation du script est xxx."
exit 0
;;
*) echo "L'utilisation du script est xxx." #Lorsqu'une option non spécifiée arrive
exit 1
;;
esac
done
echo "Nom du répertoire:${DIR_NAME}"
echo "nom de fichier:${FILE_NAME}"
Résultat d'exécution.
$ bash sample.sh -f file_name -d directory_name
Nom du répertoire: répertoire_name
Nom de fichier: fichier_name
$ bash sample.sh -f
sample.sh:Les options nécessitent des arguments-- f
L'utilisation du script est xxx.
$ bash sample.sh -k
sample.sh:Option illégale-- k
L'utilisation du script est xxx.
Pour Python3, le module argparse fournit un mécanisme puissant. Vous n'avez pas besoin d'écrire une fonction pour afficher l'aide, et contrairement à Bash, vous pouvez utiliser l'option longue. L'exemple de script et le résultat de l'exécution sont présentés ci-dessous.
sample.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
#Ajout de fonction_argument()Ajoutez des options avec.
#Deux types de notation à la fois(Exemple:"-d"、"--dir")Peut être enregistré.
#type est le type d'argument optionnel, dest est l'argument optionnel(valeur)Écrivez le nom de la variable qui stocke.
#Pour obtenir de l'aide, les implications de cette option(Texte à afficher pendant l'aide)Sera décrit.
parser = argparse.ArgumentParser()
parser.add_argument("-d", "--dir", type=str, dest="dir",
help="Écrivez le nom du répertoire utilisé dans le script")
parser.add_argument("-f","--file", type=str, dest="file",
help="Écrivez le nom de fichier utilisé dans le script")
args = parser.parse_args()
print("Nom du répertoire:%s" % args.dir)
print("nom de fichier:%s" % args.file)
Résultat d'exécution.
$ python sample.py -d directory_name -f file_name
Nom du répertoire: répertoire_name
Nom de fichier: fichier_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 Ecrire le nom du répertoire utilisé dans le script DIR
-f FILE, --file Écrivez le nom de fichier utilisé dans le script FILE
$ python sample.py -s
usage: sample.py [-h] [-d DIR] [-f FILE]
sample.py: error: unrecognized arguments: -s
Pour Bash, le débogage se fait de manière très primitive. En général, vous pratiquez probablement le débogage de script avec les options suivantes:
option | La description |
---|---|
-u | S'il existe une variable non définie, le processus se termine. |
-v | Affichez le contenu du script dans l'ordre d'exécution. Le nom de la variable est affiché tel quel. |
-x | Affichez le contenu du script dans l'ordre d'exécution. Les variables peuvent être développées pour afficher les informations de débogage |
Pour usage, donnez l'option ci-dessus à Shebang (exemple: "#! / Bin / bash -x"), Insérez "set -x" là où vous voulez démarrer le débogage du script et "set + x" où vous voulez le terminer. L'option -x affiche une commande nulle (:), vous pouvez donc insérer des commentaires qui ne sont visibles que pendant le débogage.
L'exemple de script et le résultat de l'exécution sont présentés ci-dessous.
sample.sh
#!/bin/bash -x
START="Lancer le script"
END="Fin du script"
echo ${START} #La variable est affichée à l'état développé
set +x #Options d'annulation
:Cette commande nulle n'est pas affichée
echo "Cette commande d'écho renvoie uniquement la partie chaîne de caractères"
set -x #Activation des options
:Cette commande nulle est affichée
echo "${END}"
Résultat d'exécution.
$ ./sample.sh
+ START=Lancer le script
+ END=Fin du script
+démarrer le script d'écho
Lancer le script
+ set +x
Cette commande d'écho renvoie uniquement la partie chaîne de caractères
+ :Cette commande nulle est affichée
+fin du script d'écho
Fin du script
Pour Python3, le débogage avec le débogueur pdb est possible. Pour l'utiliser, insérez "import pdb; pdb.set_trace ()" où vous voulez déboguer et Le débogueur démarre lorsque le script atteint la position d'insertion ci-dessus.
Comme je n'utilise pas pdb moi-même, j'écrirai un article auquel j'ai fait référence cette fois (je l'ajouterai dans le futur). ・ "Pdb - Débogueur Python" ・ "Astuces de débogage Python (@TakesxiSximada)" ・ "Introduction à la méthode efficace de débuck en Python"
C'est un contenu très basique, mais parce qu'il y avait des "éléments qui ont pris plus de temps à enquêter que prévu" Je vais le laisser comme un mémorandum.
En termes de remplacement de Bash par Python ・ "Quel est l'équivalent de Bash trap (détection de signal)?" ・ "Quelle fonction Python correspond aux commandes de base telles que cd / pwd / mkdir en premier lieu?" ・ "Est-il plus facile de traiter des fichiers avec sed ou awk, ou devrais-je utiliser Python?" Et il n'y a pas de fin à ce qu'il faut rechercher. Plus tard, je publierai ce contenu sur Qiita.
Python 3.x au lieu de Bash. Cela fait six mois que j'ai eu cette idée. Au cours des six derniers mois, j'ai eu une expérience douloureuse avec Python une seule fois. Le Python 3 que j'ai créé ne fonctionnait pas.
Migrer les scripts Python de l'environnement de développement (Debian 8.8) vers un autre environnement de vérification (CentOS 7.x) Quand j'ai essayé de l'exécuter sur CentOS, le script n'a pas fonctionné. La raison est que CentOS 7.x utilise 2.7 par défaut. De plus, puisqu'il s'agit d'un environnement de vérification, il n'est pas possible d'installer un nouveau package (Python3). Weeping Nous avons réécrit Python pour qu'il fonctionne de 3.x à 2.7.
De cette expérience, j'ai appris que "après avoir vérifié l'environnement d'exécution, écrivez le script". C'est important, Runtime.
Recommended Posts