Exercice en shell

Résolu
l'exo en script bash consiste à lire à partir d'un argument $1 qui sera le fichier , et à en déduire les permissions du propriétaire du groupe et des autres (o)de telle sorte avec en sortie par exemple cette forme là :

read write execute

user moi oui oui oui
group le groupe oui non non
others les autres oui non non

je débute alors j'ai du mal , voici ce que j'ai fait pour la partie la plus importante du script

!#/bin/bash
i=2 ( i compteur )
while ($i -lt 9 ) ( on part de 2 car le 1 er caractere sera le type ex -rwxrw-r--)
if ( cut -c$i | ls -l $1 == [a-z]
echo"oui"
else
echo "non"
fi
i=i+1
done

merci pour votre aide
Configuration: Windows XP
Firefox 1.5.0.11

48 réponses

Résumé de la discussion

L'exercice consiste à lire le chemin du fichier depuis l'argument $1 et à déduire les permissions du propriétaire, du groupe et des autres, afin de produire une sortie structurée. Des propositions montrent des approches variées, notamment l'utilisation de ls -l et cut pour isoler les bits de permission, ou l'usage de stat -c %A avec des substitutions. Pour chaque solution, les résultats affichent les indications utilisateur, groupe et autres, puis leur statut read, write et execute, en respectant un format lisible et compatible avec un extrait Google. D'autres propositions suggèrent d'améliorer la robustesse en gérant des espaces multiples et des noms d'utilisateurs, mais aucune solution ne doit être présentée comme définitive afin d'allonger les possibilités.

Bobot (l’IA à votre service)
  1. Modérateur
    Ton prof est un c** :-DDD

    Voilà en 13 lignes
    lami20j@debian:~/trash$ cat ccm.sh
    #!/bin/bash
    a=$(ls -l $1 | cut -d' ' -f1)
    user=$(ls -l $1 | cut -d ' ' -f3)
    groupe=$(ls -l $1 | cut -d ' ' -f4)
    u=${a:1:3} g=${a:4:3} o=${a:7:3}
    echo -e "user:$user\ngroup:$groupe\n"
    echo -e "    \t\tread\t\twrite\t\texecute"
    uu=${u//[rwx]/"\toui\t"}
    echo -e "user\t\c";echo -e ${uu//-/"\tnon\t"}
    gg=${g//[rwx]/"\toui\t"}
    echo -e "groupe\t\c";echo -e ${gg//-/"\tnon\t"}
    oo=${o//[rwx]/"\toui\t"}
    echo -e "autres\t\c";echo -e ${oo//-/"\tnon\t"}
    lami20j@debian:~/trash$ cat ccm.sh | wc -l
    13
    lami20j@debian:~/trash$ ls -l fichier
    -rwxrw-r-- 1 lami20j lami20j 81 2007-05-15 19:53 fichier
    lami20j@debian:~/trash$ sh ccm.sh fichier
    user:lami20j
    group:lami20j
    
                    read            write           execute
    user            oui             oui             oui
    groupe          oui             oui             non
    autres          oui             non             non
    lami20j@debian:~/trash$
    
    1
    1. Modérateur
      Salut,

      quelque chose comme ça?!
      le script
      lami20j@debian:~/trash$ cat lister_droits.sh
      #!/bin/bash
      
      droits=$(ls -l $1 | cut -d' ' -f1)
      user=$(ls -l $1 | cut -d ' ' -f3)
      groupe=$(ls -l $1 | cut -d ' ' -f4)
      
      u=${a:1:3} # user
      g=${a:4:3} # group
      o=${a:7:3} # other
      
      echo user:$user
      echo -e "group:$groupe\n"
      
      echo -e "    \t\tread\t\twrite\t\texecute"
      
      echo -e "user\t\c"
      echo $u | sed s/[rwx]/\\toui\\t/g | sed s/-/\\tnon\\t/g
      
      echo -e "groupe\t\c"
      echo $g | sed s/[rwx]/\\toui\\t/g | sed s/-/\\tnon\\t/g
      
      echo -e "autres\t\c"
      echo $o | sed s/[rwx]/\\toui\\t/g | sed s/-/\\tnon\\t/g
      
      ls sur le fichier
      lami20j@debian:~/trash$ ls -l test01.txt
      -rw-r--r-- 1 lami20j lami20j 64 2007-05-10 19:06 test01.txt
      
      exécution de script
      ami20j@debian:~/trash$ sh lister_droits.sh test01.txt
      user:lami20j
      group:lami20j
      
                      read            write           execute
      user            oui             oui             non
      groupe          oui             non             non
      autres          oui             non             non
      
      --
      lami20j
      0
      1. merci pour ta réponse lami20j , on a pas encore vu les fcts "sed" ni le type
        {a:1:3} ça correspond à quoi ??
        on doit le faire avec les boucles , mais si je trouve pas , je prends ta méthode que je suis en train de tester et qui a l'air de marcher ;
        yacine
        0
      2. Modérateur
        Re,

        une petite corection
        au lieu de
        droits=$(ls -l $1 | cut -d' ' -f1)
        écrit
        a=$(ls -l $1 | cut -d' ' -f1)

        sed n'est pas une fonction
        regarde ici sed et ici sed

        {a:1:3} ça correspond à quoi ??
        regarde ici man bash

        ${paramètre:début:longueur}
        Extraction de sous-chaîne Se développe pour fournir la sous-chaîne de la longueur indiquée (en caractères) commençant au début.D offset. Si la longueur est omise, fournit la sous-chaîne commençant au caractère de début et s'étendant jusqu'à la fin du paramètre. La longueur et le début sont des expressions arithmétiques (voir ÉVALUATION ARITHMÉTIQUE plus bas). La longueur doit être positive ou nulle. Si le début est négatif, sa valeur est considérée à partir de la fin du contenu du paramètre. Si le paramètre est @, le résultat correspond aux longueur paramètres positionnels commençant au début. Si le paramètre est un nom de tableau indexé par @ ou *, le résultat est les longueur membres du tableau commençant à ${paramètre[début]}. L'indexation des sous-chaînes débute à zéro, sauf pour les paramètres positionnels qui débute en 1.

        0
    2. Modérateur
      Salut,

      Autre solution (assez proche) :
      #! /bin/bash
      
      echo -e "\tread\twrite\texecute\n"
      
      read user group others < <(stat -c "%A" $1 | sed -e 's/-//;s/.../& /g')
      echo -e "User\c"; echo $user | sed 's/[rwx]/\toui/g;s/-/\tnon/g'
      echo -e "group\c"; echo $group | sed 's/[rwx]/\toui/g;s/-/\tnon/g'
      echo -e "Others\c"; echo $others| sed 's/[rwx]/\toui/g;s/-/\tnon/g'
      Rend le script exécutable et lances-le par :
      ./le_script
      ;-))
      0
      1. en effet avec la commande sed c mieux !
        merci bcp à tous les 2 pour vos réponses ;
        0
        1. re bonjour ,
          en fait on nous le demande de le faire sans les commandes SED et AWK, alors comment remplacer des caracteres sans sed ?
          0
          1. Modérateur
            Re-

            Essaye ça alors :
            #! /bin/bash
            
            var=$(ls -l "$1" | cut -d" " -f1)
            usere=$(echo "$var" | cut -c2-4)
            groupe=$(echo "$var" | cut -c5-7)
            autres=$(echo "$var" | cut -c8-10)
            
            echo -e "$usere\n$groupe\n$autres" > fichier.txt
            echo -e "\t\tread\twrite\texecute\n"
            
            i=1
            while read line
            do
            if [ "$i" == 1 ]
            then param=user
            elif [ "$i" == 2 ]
            then param=groupe
            else param=others
            fi
            case "$line" in
            ---)    echo -e "$param\t\tnon\tnon\tnon"
                    ;;
            --x)    echo -e "$param\t\tnon\tnon\toui"
                    ;;
            -w-)    echo -e "$param\t\tnon\toui\tnon"
                    ;;
            -wx)    echo -e "$param\t\tnon\toui\toui"
                    ;;
            r--)    echo -e "$param\t\toui\tnon\tnon"
                    ;;
            r-x)    echo -e "$param\t\toui\tnon\toui"
                    ;;
            rw-)    echo -e "$param\t\toui\toui\tnon"
                    ;;
            rwx)    echo -e "$param\t\toui\toui\toui"
                    ;;
            esac
            i=$(expr $i + 1)
            done < fichier.txt
            ;-))
            0
            1. Modérateur
              Salut,

              autre solution :-))
              Le script
              lami20j@debian:~/trash$ cat ccm.sh
              #!/bin/bash
              
              a=$(ls -l $1 | cut -d' ' -f1)
              user=$(ls -l $1 | cut -d ' ' -f3)
              groupe=$(ls -l $1 | cut -d ' ' -f4)
              
              u=${a:1:3} # user
              g=${a:4:3} # group
              o=${a:7:3} # other
              
              echo user:$user
              echo -e "group:$groupe\n"
              echo -e "    \t\tread\t\twrite\t\texecute"
              
              uu=${u//[rwx]/"\toui\t"}
              echo -e "user\t\c"
              echo -e ${uu//-/"\tnon\t"}
              
              gg=${g//[rwx]/"\toui\t"}
              echo -e "groupe\t\c"
              echo -e ${gg//-/"\tnon\t"}
              
              oo=${o//[rwx]/"\toui\t"}
              echo -e "autres\t\c"
              echo -e ${oo//-/"\tnon\t"}
              

              Le résultat
              lami20j@debian:~/trash$ ls -l fichier
              -rwxrw-r-- 1 lami20j lami20j 81 2007-05-15 19:53 fichier
              lami20j@debian:~/trash$ sh ccm.sh fichier
              user:lami20j
              group:lami20j
              
                              read            write           execute
              user            oui             oui             oui
              groupe          oui             oui             non
              autres          oui             non             non
              
              0
              1. ah merci beaucoup pour vos réponses ,je suis en train de tester , mais le pire c est qu'ils demandent une réponse en moins de 16 lignes ....
                0
                1. Modérateur
                  Voilà montre à ton(tes prof) dans 2 lignes :-DDDDDDDDDDDDd
                  #!/bin/bash
                  a=$(ls -l $1 | cut -d' ' -f1);user=$(ls -l $1 | cut -d ' ' -f3);groupe=$(ls -l $1 | cut -d ' ' -f4);u=${a:1:3} g=${a:4:3} o=${a:7:3};echo -e "user:$user\ngroup:$groupe\n";echo -e "    \t\tread\t\twrite\t\texecute";uu=${u//[rwx]/"\toui\t"};echo -e "user\t\c";echo -e ${uu//-/"\tnon\t"};gg=${g//[rwx]/"\toui\t"};echo -e "groupe\t\c";echo -e ${gg//-/"\tnon\t"};oo=${o//[rwx]/"\toui\t"};echo -e "autres\t\c";echo -e ${oo//-/"\tnon\t"}
                  

                  la preuve
                  lami20j@debian:~/trash$ cat ccm.sh | wc -l
                  2
                  


                  P.S. J'espère qu'il n'a pas fixer la longueur de lignes à 1 caractère :-DDD
                  0
                  1. ouaou bravo !! merci encore , je lui dirai que c est un gros c...
                    merci
                    0
                    1. Modérateur
                      Bon, en oubliant un peu la demande saugrenue de ton prof, voici une optimisation de ma version, cette fois en 9 lignes et sans rigolade :-))
                      (je ne compte pas cette fois la ligne #!/bin/bash )
                      #!/bin/bash
                      a=$(ls -l $1 | cut -d' ' -f1)
                      b=${a//[rwx]/"\toui\t"}
                      aa=${b//-/"\tnon\t"}
                      user=$(ls -l $1 | cut -d ' ' -f3)
                      groupe=$(ls -l $1 | cut -d ' ' -f4)
                      u=${aa:7:21} g=${aa:21:21} o=${aa:42:21}
                      echo -e "user:$user\ngroup:$groupe\n"
                      echo -e "    \t\tread\t\twrite\t\texecute"
                      echo -e "user\t$u\ngroupe\t$g\nautrese\t$o"
                      

                      0
                      1. il veut en moins de 16 lignes pour éviter les if ..then else ...fi à répétition
                        ensuite je sais pas pourquoi il a choisi ce chiffre , il a du avoir des exemples en 16 lignes avec des if à répétition mais déjà je vois pas comment c'est possible ; j'irai pas le perturber c est déjà assez complexe comme ça ;
                        a plus ;-))
                        0
                        1. Modérateur
                          d'accord
                          en final tu peux prendre la version en 9 lignes message N°13
                          0
                      2. Est ce que vous puvez à trouver un ensemble d'exercices corrigés concernant la programmation en shell sous linux.
                        0
                        1. slt je voudrais juste un petit script pour faire la fusion de 2 fichiers en un fichier unique
                          0
                          1. Modérateur
                            Salut,

                            pas besoin de script, une commande est suffisante
                            disons que tu as 2 fichiers : fichier1.txt et fichier2.txt
                            pour ajouter fichier2.txt à la fin de fichier1.txt
                            tu tapes
                            cat fichier2.txt >> fichier1.txt
                            si tu veux garder les fichier originaux tu peux faire
                            cat fichier1.txt fichier2.txt > fichier3.txt
                            0
                            1. j'avais cette option mais je pensais kon pouvai le faire aussi a l'aide d'un script. En tout cas merci bc!!!!
                              0
                              1. bonjour,

                                J'espère que vous allez bien, dans la nuit !

                                Jipicy :

                                Ta solution pour le problème des permissions, fonctionne, comme celui de lami. Merci pour vos solutions!
                                J'ai choisi ta solution, car plus facile, pour moi, à modifier.

                                Je veux que le script m'affiche aussi mon nom de login, ce que je n'ai pas !

                                Modification de script
                                :

                                #! /bin/bash

                                <gras>var=$(ls -l "$1" | cut -d" " -f1)
                                owner=$(echo "$var" | cut -c2-4)
                                group=$(echo "$var" | cut -c5-7)
                                everybody=$(echo "$var" | cut -c8-10)

                                echo -e "$owner\n$group\n$everybody" > fichier.txt
                                echo "read write execute"

                                i=1
                                while read line
                                do
                                if [ "$i" == 1 ]
                                then param=owner
                                elif [ "$i" == 2 ]
                                then param=group
                                else param=everybody
                                fi
                                case "$line" in
                                ---) echo "$paramt non non non"
                                ;;
                                --x) echo "$param non non oui"
                                ;;
                                -w-) echo "$param non oui non"
                                ;;
                                -wx) echo "$param non oui oui"
                                ;;
                                r--) echo "$param oui non non"
                                ;;
                                r-x) echo $param oui non oui"
                                ;;
                                rw-) echo "$param oui oui non"
                                ;;
                                rwx) echo "$param oui oui oui"
                                ;;
                                esac
                                i=$(expr $i + 1)
                                done < fichier.txt



                                Résultat
                                : good (mais manque loginname)

                                read write execute
                                owner oui oui non
                                group oui non non
                                everybody oui non non


                                la recherche continue

                                Merci beaucoup

                                a+
                                0
                                1. Bonjour à tous!

                                  J'émerge ....

                                  problème en suspens : afficher mon login, à côté de owner : voir post au dessus.

                                  travail effectué :

                                  J'ai introduit $USER, à côté de, owner, mais le résultat est décevant : owner est soit collé à mon login, si je ne mets pas d'espace entre owner et $USER, ou n'apparait pas s'il y un espace.

                                  contribution bien bienvenue

                                  a+
                                  0
                                  1. Bon je te donne quand même la soluce que j'ai trouvé.
                                    #!/bin/bash
                                    on=$(ls -l $1 | cut -d" " -f3)
                                    gn=$(ls -l $1 | cut -d" " -f4)
                                    gr=$(ls -l $1 | cut -c5)
                                    gw=$(ls -l $1 | cut -c6)
                                    ge=$(ls -l $1 | cut -c7)
                                    er=$(ls -l $1 | cut -c8)
                                    ew=$(ls -l $1 | cut -c9)
                                    ee=$(ls -l $1 | cut -c10)
                                    if [ [ -r $1 ]]
                                    then or="YES"
                                    else or="NO"
                                    fi
                                    if [ [ -w $1 ]]
                                    then ow="YES"
                                    else ow="NO"
                                    fi
                                    if [ [ -x $1 ]]
                                    then oe="YES"
                                    else oe="NO"
                                    fi
                                    if [ [ $gr = "r" ]]
                                    then grr="YES"
                                    else grr="NO"
                                    fi
                                    if [ [$gw = "w" ]]
                                    then grw="YES"
                                    else grw="NO"
                                    fi
                                    if [ [$ge = "x" ]]
                                    then gre="YES"
                                    else gre="NO"
                                    fi
                                    if [ [$er = "r" ]]
                                    then evr="YES"
                                    else evr="NO"
                                    fi
                                    if [ [$ew = "w" ]]
                                    then evw="YES"
                                    else evw="NO"
                                    fi
                                    if [ [$ee = "x" ]]
                                    then eve="YES"
                                    else eve="NO"
                                    fi
                                    echo -e "                               "READ     WRITE   EXECUTE
                                    echo -e OWNER $on"            "$or"   "$ow"   "$oe
                                    echo -e GROUP $gn"                     "$grr"   "$grw"    "$gre
                                    echo -e EVERYBODY"                       "$evr"   "$evw"    "$eve
                                    

                                    Bon il est vraiment trop long mais au moins il marche :)))))))
                                    Par contre il y a quelques idées qui commence a me trotter dans la tête, je vais promener ma bête et je me met là dessus.
                                    0
                                    1. Salut tout le monde!

                                      hug, pour ton script, en le modifiant un peu, il donne :

                                      READ WRITE EXECUTE
                                      OWNER moi YES YES YES
                                      GROUP users YES NO NO
                                      EVERYBODY YES NO NO

                                      pas mal !

                                      merci

                                      Autre problème du jour :

                                      je dois afficher :

                                      NOM
                                      PID TTY TIME CMD
                                      différents applis
                                      différents process

                                      -----
                                      pour chaque utilisateur connecté: ce qui donne :

                                      nono
                                      PID TTY TIME CMD
                                      31799 pts/3 00:00:00 vim
                                      31866 pts/3 00:00:00 vim
                                      2495 pts/7 00:00:00 vim
                                      8368 pts/0 00:00:00 vim
                                      9544 pts/2 00:00:00 ps

                                      bobo
                                      PID TTY TIME CMD
                                      8368 pts/0 00:00:00 vim
                                      9544 pts/2 00:00:00 ps

                                      ainsi de suite , pour tous les connectés.

                                      la sortie doit être enregistré dans un fichier .

                                      -----

                                      travail déjà effectué
                                      :

                                      test en mode ligne de commande, mode synchrone ou séquentielle :

                                      echo -e "$USER\n"; ps


                                      résultat
                                      :

                                      moi

                                      PID TTY TIME CMD
                                      9339 pts/1 00:00:00 bash
                                      9970 pts/1 00:00:00 ps

                                      Comment le faire pour x users connectés? Et, bien sûr, chacun ne doit apparaitre qu'une seule fois. s'il était possible de le coller davantage, aussi, ce serait bien: je veux dire, décaler, si possible, les colonnes vers lla gauche, de telle manière, qu'elles soient alignées à gauche, avec le NOM.

                                      Merci à tous, merci pour vos contributions

                                      la recherche continue

                                      a+
                                      0
                                      • 1
                                      • 2
                                      • 3