Menu

Comment intégrer un code bash dans pyhton

Messages postés
3
Date d'inscription
lundi 6 mai 2019
Statut
Membre
Dernière intervention
6 mai 2019
-
Salut tout le monde, je cherche exécuter une commande bash par l'intermédiaire de python car je n'ai pas la possibilité d'installer le module OTB qui n'est pas compatible avec mon PC.
J'ai besoin de calculer des indices multispectraux par cette commande bash puis ensuite les intégrer à une matrice déjà existante. Mais pour le moment je n'arrive pas a faire fonctionner ma commande ...

Mon code est le suivant :

import os
import fnmatch

src_directory = "/run/media/afavro/Elements/Acquisitions_Copernicus2/1/S2/4_reflectance/"
dossier = os.listdir (src_directory)
print(dossier)

for fichier in dossier:
        print (fichier)
        ssrc_directory = "/run/media/afavro/Elements/Acquisitions_Copernicus2/1/S2/4_reflectance/" + fichier + "/"
        rasters = os.listdir (ssrc_directory) 
        print(rasters) 
    
    for img in rasters:
        print (img)

        INPUT_FOLDER = ssrc_directory
        print(INPUT_FOLDER)
            
        OUTPUT_FOLDER = "/run/media/afavro/Elements/Acquisitions_Copernicus2/1/S2/5_indices/" + fichier + "/"
        print(OUTPUT_FOLDER)
                   
        def findRasters (path, filter):
            for root, dirs, files in os.walk(path):
                for file in fnmatch.filter(files, filter):
                    yield file
          
        
        for raster in findRasters(INPUT_FOLDER, '*.hdr'):
            print(raster)
            inRaster = ssrc_directory + raster
            print(inRaster)
            outRaster = OUTPUT_FOLDER + 'indices2_' + img
            print (outRaster)
            cmd = 'otbcli_RadiometricIndices -in inRaster -list Soil:BI Vegetation:MSAVI Vegetation:SAVI -out outRaster'         
            os.system(cmd)



En message d'erreur il m'est dit que l'image inRaster ne peut pas être ouverte mais je ne comprend pas pourquoi; Auriez-vous une idée ?
Afficher la suite 

Votre réponse

1 réponse

Messages postés
28814
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
10 mai 2019
8028
0
Merci
Bonjour,

Question préalable

Quand tu dis que le module OTB n'est pas compatible avec ton PC, peux-tu clarifier (message d'erreur, etc) ?

Sous Linux Ubuntu par exemple, ce module peut s'installer avec la commande sudo apt install
python3-otb
.

En effet, passer par le module python sera plus propre que passer par une commande shell.

Appeler une commande shell en python

Personnellement, j'utilise plutôt
Popen
, cela permet en outre de récupérer les flux (sortie standard et sortie d'erreur) :

Voici un exemple fonctionnel pour appeler graphviz, dans ton cas il suffirait d'adapter la valeur de la variable
cmd
, de renommer la fonction et de retravailler ses paramètres, le message d'erreur, et enfin de renommer la variable
dot
en par exemple
otb
:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from subprocess import Popen, PIPE

def run_graphviz(s_dot, layout_engine = "dot", format = "svg") -> bytes:
    """
    Convert a dot string (graphviz format) into a graphic file.
    Args:
        s_dot: A string in the graphviz format.
        layout_engine: The graphviz engine used for the rendering.
            See "man dot" for more details.
        format: The output graphviz terminal.
            See "man dot" for more details.
    Returns:
        The bytes of the output image iff successful, None otherwise.
    """
    cmd = ['dot', '-T' + format, '-K', layout_engine]
    dot = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
    stdoutdata, stderrdata = dot.communicate(s_dot.encode("utf-8"))
    status = dot.wait()
    if status == 0:
        return stdoutdata.decode("utf-8")
    else:
        fstr = "dot returned {}\n[==== stderr ====]\n{}"
        print(fstr.format(status, stderrdata.decode('utf-8')))
        print("Input dot string was:\n%s\n" % s_dot);
        raise RuntimeError("run_graphviz: invalid string")


Conseils concernant ton code
  • Déclarer une fonction dans une boucle n'est pas l'endroit le plus indiqué, mieux vaut la déclarer en début de fichier.
  • Pour améliorer la lisibilité de ton code, il serait préférable de déclarer tes variables globales (chemins...) en début de fichier et de leur donner un nom tout en capitales.
  • Généralement on met le programme principale dans une fonction (e.g.
    main
    ) ce qui permet par la suite de définir des points d'entrée (voir
    setup.py
    ).


#!/usr/bin/env python3
# -*- coding: utf-8 -*-

def main():
    # programme

if __name__ == '__main__':
    main()
    sys.exit(0)


Bonne chance
AxelleF_11
Messages postés
3
Date d'inscription
lundi 6 mai 2019
Statut
Membre
Dernière intervention
6 mai 2019
-
Je ne sais pas exactement pour quelles raisons otb ne peut être installer sur mon PC, l'informaticien de m'a structure n'y ai pas parvenu :/
Super merci, je vais essayer avec ça !
AxelleF_11
Messages postés
3
Date d'inscription
lundi 6 mai 2019
Statut
Membre
Dernière intervention
6 mai 2019
-
voici le message d'erreur qui apparait quand je tente d'installer le module otb :

Collecting package metadata: done
Solving environment: failed

PackagesNotFoundError: The following packages are not available from current channels:

- python3-otb

Current channels:

- https://conda.anaconda.org/conda-forge/linux-64
- https://conda.anaconda.org/conda-forge/noarch
- https://conda.anaconda.org/r/linux-64
- https://conda.anaconda.org/r/noarch
- https://repo.anaconda.com/pkgs/main/linux-64
- https://repo.anaconda.com/pkgs/main/noarch
- https://repo.anaconda.com/pkgs/free/linux-64
- https://repo.anaconda.com/pkgs/free/noarch
- https://repo.anaconda.com/pkgs/r/linux-64
- https://repo.anaconda.com/pkgs/r/noarch

To search for alternate channels that may provide the conda package you're
looking for, navigate to

https://anaconda.org

and use the search bar at the top of the page.
mamiemando
Messages postés
28814
Date d'inscription
jeudi 12 mai 2005
Statut
Modérateur
Dernière intervention
10 mai 2019
8028 -
Attention, le nom que je t'ai donné correspond au paquet debian donc pour une installation avec
apt
! Donc sous Debian/Ubuntu/... tu lancerais :

sudo apt-get update
sudo apt-get install python3-otb


Dans ton cas tu as décidé de ne pas utilisé le python "standard" fourni par linux, mais d'installer anaconda. Cela signifie que tu as un 2e python installé, dans son répertoire propre, et avec ses modules propres.

Comme tu l'as fait, il est naturel de passer par
conda
. Par contre, les paquets Conda ne sont nommés comme dans apt, mais plutôt comme dans python. Ici, en toute logique ce serait par exemple
conda install otb
. Malheureusement, ce paquet n'existe pas actuellement. À moins de trouver un dépôt anaconda on n'y arrivera pas comme ça.

Si tu souhaites absolument utiliser conda, il faudra installer autrement.

Méthode 1 : installation via le gestionnaire de paquets (recommandée)

En admettant que tu sois sous debian/ubuntu :
sudo apt-get update
sudo apt-get install python3-otb


Méthode 2 : installation manuelle

On suit la procédure d'installation officielle :

1) Installer les dépendances.

Exemple sous debian/ubuntu :
sudo apt-get update
sudo apt-get install libx11-6 libxext6 libxau6 libxxf86vm1 libxdmcp6 libdrm2


2) Installer otb :
wget https://www.orfeo-toolbox.org/packages/OTB-6.6.1-Linux64.run
chmod +x OTB-6.6.1-Linux64.run
./OTB-6.6.1-Linux64.run


Rendre otb accessible avec le python fourni par anaconda

À ce stade, tu devrais pouvoir faire marcher otb depuis ton interpréteur python standard :

/usr/bin/python3


Puis dans l'interpréteur :

import otbApplication


Tu peux notamment voir dans quels répertoire
python3
cherche ses modules :

import os
print(os.sys.path)


Mais si tu lances juste
python3
, conformément à ce qui est retourné par la commande
echo $PATH
, c'est l'interpréteur d'anaconda qui sera lancé. Et si tu répètes les mêmes commandes, notamment afficher
os.sys.path
, tu verras qu'il ne cherche pas au mêmes endroits.

Dès lors, deux manières de corriger.
a) Soit tu rajoutes dans les répertoires de modules d'anaconda un lien symbolique vers l'endroit où est stocké otb (c'est ce que suggère la documentation officielle, avec la commande
ln -s
)
b) Soit tu corriges la variable
os.sys.path
pour garantir qu'elle contient le bon répertoire.

Bonne chance
Commenter la réponse de mamiemando