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. hi Hug!

    justement je cehrchais à amaigrir encore celui des permissions, mais des problèmes persistent...au niveau des boucles if !

    je vais tester cette nouvelle nouvelle !

    Merci pour ta proposition (je t'enregistre°

    A+
    0
    1. "désolé! pour ton bébé! je l'ai amoindri ...:) "

      lol pas de souci, il était obèse de toute façon :)))) mais voilà un version encore plus light ( 1 ligne), malheureusement je passe toujours pas un fichier temporaire(temp) mais ça donne le même résultat, je vais voir après pour éviter l'utilisation d'un fichier.

      #!/bin/bash
      finger -l | grep Name > temp ; who | cut -d" " -f1 | while read lines ; do grep $lines temp | cut -d":" -f3 ; ps -u $lines ; done ; rm temp
      


      je vais regarder pour ton autre exercice, ça doit pas être bien compliqué.

      P.s.: si t'as besoin d'aide même a 3heure du mat, prend mon addresse msn, mon staut est hors ligne mais je suis tout le temps connecté.

      anarcopunx_7@hotmail.com n'hésite pas même si il est très tard ( tôt... )
      0
      1. hi!

        "Ça marche bien dans un terminal... "

        certainement, et je te crois, preuve, à l'appui, mais je suis en mode asp!

        je pense à installer un linux, avec VMWare, en local, même avec un live! Mais je ne l'ai pas encore fait !

        sinon, merci pour le script : tu est trop fou! tu m'as encore grillé ! ça me donne du boulot, encore !

        Problème du jour :

        Ecrire un programme shell reconnaitre qui demande à l’utilisateur d’entrer un mot, puis suivant le première caractère de ce mot, indique s’il commence par un chiffre, une minuscule, une majuscule ou une autre sorte de caractère.

        merci

        a+:))

        ps : dire que le prof a donné cet exo, un cours en ligne, après un cours sur : structure de contrôle : case et while!
        0
        1. salut tout le monde !

          d'abord, merci pour lien de man, sur le net, ça aide et c'est plus pratique que de retourner, dans help, de bash.

          lami, je reviens sur ton script :

          for i in $(grep "$(who | cut -d' ' -f1)" /etc/passwd);do echo -e "$i\n" | cut -d':' -f5;ps -opid,tname,time,comm -U ${i%%:*};done

          pour moi, il affiche, mon prénom deux fois, et les autres, toujours le prénom, une seule fois !

          alors, le message d'erreur, affiche les bonnes options, à mettre : j'ai essayé avec quelques unes, toujours pas de résultat.

          mais,il est intéressant, il m'a permis de poursuivre mes tests, de comprendre mieux : cut -opt, et d'oser des choses !

          Hug,

          désolé! pour ton bébé! je l'ai amoindri ...:) => résultat: j'ai exactement ce que je voulais ! (pid est aligné vers la droite, parfait! ce qui n'est pas visible sur la capture d'écran, mais lance-le, alors tu verras!)
          ----------------------------------------------------------------------------
          #!/bin/bash

          finger -l | grep Name > temp

          echo > who_process
          who | cut -d" " -f1 | while read lines

          do

          grep $lines temp | cut -d":" -f3 >> who_process
          ps -u $lines >> who_process
          echo >> who_process

          done

          rm temp | echo "List of user(s) and process running have been saved to the file who_process"

          exit

          -----------------------------------------------------------------------------

          résultat
          :

          Toi
          PID TTY TIME CMD
          12956 ? 00:00:04 sshd
          12957 pts/3 00:00:00 bash
          1109 pts/3 00:00:00 vim

          Moi
          PID TTY TIME CMD
          29539 ? 00:00:00 sshd
          29540 pts/5 00:00:00 bash
          1135 pts/5 00:00:00 sh
          1140 pts/5 00:00:00 sh
          1149 pts/5 00:00:00 ps


          salutations à jipi!

          merci à tous !

          a+

          :)

          ps : là, je vais déjeuner, ouf!
          0
          1. par contre, jipi, il marche en mode script seulement, ton script de Nom, pas en ligne de commande, alors, que ce ne sont que des commandes internes que tu utilises, je crois!

            mystère ! mais peut-être pas tant que ça !

            a+
            0
            1. Modérateur
              Re-

              J'ai pas compris ton problème là !? ;-\
              $ NAME=$(finger -l | grep Name)
              $ echo ${NAME##*: }
              Jean-Philippe
              Ça marche bien dans un terminal...

              problème du jour :

              Ecrire un programme shell 4arg qui vérifie que le nombre d'arguments passés lors de l’appel du programme est égal à 4 et écrit suivant le cas le message “Correct” ou le message “Erreur"


              Pas besoin de boucles ni de "case ... esac", une simple condition "if ... then ... else... fi" suffit :
              #! /bin/bash
              
              if [ "$#" != "4" ]
              then echo "Erreur"
              else echo "Correct"
              fi
              ;-))
              0
          2. salut tout le monde !

            je reviens ver vous ...au sujet de mon problème de users et de process !

            j'ai testé la solution de hug...astucieux! et ça marche ! même si, c'est moins économique, peut-être comme solution.

            par contre, il y a une chose, que je ne comprends pas encore, même après l'avoir décortiqué et réalisé, pas à pas, pour comprendre.

            explication : je veux toujours comprendre et jamais recopié sans comprendre et, cela peut prendre du temps, parfois, avec les 'fous furieux' et appréciables développeurs, que nous avons ici : lami et jipi , et peut-être rejoint bientôt par un troisième larron, mais moin 'fou', pour le moment!

            Explication :

            finger -l | grep Name > temp => liste un user connectés avec process, sans les headers, en cours et tu prends son login, nom, son rep, son shell, et autres, puis tu envois cela dans une commande grep, qui récupère le nom, ensuite tu sauvegardes dans un fichier , temp, non pas Name, seulement, mais name et login :ok => a

            finger -l (moi, seulement à ce moment là)

            Login: moi Name: Mom nom
            Directory: /home/moi Shell: /bin/bash
            On since Sat Feb 9 22:08 (GMT) on pts/1 from 83.204.133.98 # temp
            No mail.
            No Plan.

            finger -l | grep Name

            login: moi Name: mon nom

            echo " " > who_process => création d'un fichier , who_process, dans lequel, tu crées, un espace vide vertical, quelques lignes, pour users connectés

            who => moi pts/1 2008-02-09 22:08 (xx.xxx.xxx.xx) (moi, seulement, à ce moment là)

            who | cut -d" " -f1 | while read lines => tu prends ces users connectés, et tu extrais, les infos : login, machine (pts) , puis tu lis les lignes tant que le code de retour n'est pas différent de zéro.

            do
            grep $lines temp | cut -d":" -f3 >> who_process => tu prends dans temp, le troisième champ : Name, que tu envois dans who_process, pour lequel, tu avais déjà créé la place (echo " ")

            echo " " >> who_process => encore un espace vertical dans who_process ( quelques lignes)

            ps -u $lines >> who_process => tu récupères les en-têtes

            USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
            1553 30318 0.0 0.0 4624 1520 pts/1 Ss 22:08 0:00 -bash
            1553 30426 0.0 0.0 4220 940 pts/1 R+ 22:28 0:00 ps -u

            echo " " >> who_process => encore un espace dans le fichier
            done
            rm temp | echo "List of user(s) and process running have been saved to the file who_process" => supprime le fichier temp et reste, bien echo "xxxxxxxxx" pas mal vu ! c'est le même principe qu'avec le mot à insérer au milieu du texte, moité du nbre de lignes.
            exit

            je récapitule :

            1. crées deux fichier, dans le premier, temp, tu mets une partie de ce que tu cherches et dans l'autre un espace pour une info dans contenu dans le premier

            2. tu dis par une boucle while read, de créer autant d'espace nécessaire (echo " "), qu'il y aura de connectés à inséser

            3. tu récupères les en-têtes, que tu cherches aussi à insérer (ps -u) et tu demandes toujours dans la boucle de créer autant d'espace nécessaire pour les recevoir

            4. tu détruis le fichier temp (logique) et tu informes l'utilisateur sur le lieu de la consultation. En effet, sinon, c'est inquiétant !

            Question
            : comment tu fais dans le 3., pour virer les autres en-têtes, que tu ne souhaites ! ( je n'ai pas encore compris, car j'ai vérifié pas à pas, mais en vain, pour le moment)

            jipi :

            ton script pour le nom (Name) est bon : impec !

            problème du jour :

            Ecrire un programme shell 4arg qui vérifie que le nombre d'arguments passés lors de l’appel du programme est égal à 4 et écrit suivant le cas le message “Correct” ou le message “Erreur"

            travail effectué : j'ai du mal avec les boucles !

            shopt -s extglob

            case $1 in

            +(:digit=4: ) echo " correct" # il ne prend pas les crochets!

            comment écrire l'autre cas! je n'ai encore trouvé la solution encore!

            ;;

            esac


            merci

            a+
            0
            1. Modérateur
              Un raccourci pour l'affichage du nom :
              NAME=$(finger -l | grep Name)
              echo ${NAME##*: }
              ;-))
              0
              1. Salut,
                j'ai pas mal galérer avec le nom aussi mais au final je suis quand même parvenu a le faire afficher, par contre dans mon exercice je devais faire apparaitre le username sans le point entre le prénom et le nom.

                finger -l | grep Name > temp 
                echo " " > who_process
                who | cut -d" " -f1 | while read lines
                    do
                      grep  $lines temp | cut -d":" -f3 >> who_process
                      echo " " >> who_process
                      ps -u $lines >> who_process
                      echo " " >> who_process
                    done
                rm temp | echo "List of user(s) and process running have been saved to the file who_process"
                exit
                


                Et voilà....
                0
                1. Modérateur
                  chez moi fonctionne
                  ça sera bien si tu montreras aussi les commandes que tu tapes, pour voir s'il n'y a pas une erreur quelque part
                  0
                  1. lami, ton script

                    résultat, extrait: et cela après chaque connecté, prénom affiché seulement.

                    Donald

                    PID TTY TIME COMMAND
                    15762 ? 00:00:00 sshd
                    15763 pts/4 00:00:00 bash
                    15786 pts/4 00:00:00 sqlplus
                    15787 ? 00:00:04 oracle

                    ERROR: User name does not exist.
                    ********* simple selection ********* ********* selection by list *********
                    -A all processes -C by command name
                    -N negate selection -G by real group ID (supports names)
                    -a all w/ tty except session leaders -U by real user ID (supports names)
                    -d all except session leaders -g by session OR by effective group name
                    -e all processes -p by process ID
                    T all processes on this terminal -s processes in the sessions given
                    a all w/ tty, including other users -t by tty
                    g OBSOLETE -- DO NOT USE -u by effective user ID (supports names)
                    r only running processes U processes for specified users
                    x processes w/o controlling ttys t by tty
                    *********** output format ********** *********** long options ***********
                    -o,o user-defined -f full --Group --User --pid --cols --ppid
                    -j,j job control s signal --group --user --sid --rows --info
                    -O,O preloaded -o v virtual memory --cumulative --format --deselect
                    -l,l long u user-oriented --sort --tty --forest --version
                    -F extra full X registers --heading --no-heading --context
                    ********* misc options *********
                    -V,V show version L list format codes f ASCII art forest
                    -m,m,-L,-T,H threads S children in sum -y change -l format
                    -M,Z security data c true command name -c scheduling class
                    -w,w wide output n numeric WCHAN,UID -H process hierarchy

                    jipi :

                    résultat : seulement le prénom est affiché :

                    prénom (un seul, le mien)

                    j'essaye de comprendre le message d'erreur et d'en tirer profit

                    merci de votre contribution

                    La recherche continue

                    a+
                    0
                    1. Modérateur
                      comme ça?!
                      for i in $(grep "$(who | cut -d' ' -f1)" /etc/passwd);do echo -e "$i\n" | cut -d':' -f5;ps -opid,tname,time,comm -U ${i%%:*};done
                      
                      0
                      1. en fait, il faudrait pouvoir extraire mon nom de la sortie de la cmd: grep $USER < /etc/passwd :

                        moi:x:1553:100:Mon nom:/home/moi:/bin/bash

                        ou même de finger :moi Mon nom pts/1 Feb 9 11:05

                        je pensais à cut, mais il y a déjà un cut: mettre un 2è demande réflexion!

                        a+
                        0
                        1. Modérateur
                          Voir post #39

                          Sinon tu peux aussi :
                          finger -sp $USER | tail -1 | tr -s "[ ]*" ":" | cut -d: -f2
                          Mais c'est plus tordu ;-))

                          Édit : Oups ;-((
                          finger -sp $USER | tail -1 | tr -s "[ ]" ":" | cut -d: -f2
                          ;-))
                          0
                      2. au fait, pourquoi je devais faire cela ?

                        a+
                        0
                        1. je vois beaucoup de monde! c'est une formation en ligne ...

                          Mais il n'y a que moi, de connecté, en ce moment (w)

                          a+
                          0
                          1. j'étais justement là-dessus, pour essayer de comprendre, comment résoudre ce problème de nom réel et login.

                            question : en mode asp, comment faire pour copier en local, man ps, par ex.

                            merci d'avance

                            a+
                            0
                            1. Modérateur
                              affiche
                              cat /etc/passwd
                              0
                              1. nickel pour TTY !

                                Mais comme une épine dans le pied, il reste mon login, au lieu de mon nom réel !

                                capture écran :

                                moi
                                PID TTY TIME COMMAND
                                15144 ? 00:00:00 sshd
                                15145 pts/1 00:00:00 bash
                                15302 pts/1 00:00:00 sh
                                15307 pts/1 00:00:00 ps
                                toi
                                PID TTY TIME COMMAND
                                15174 ? 00:00:00 sshd
                                15175 pts/2 00:00:00 bash
                                15299 pts/2 00:00:00 more

                                merci

                                a+
                                0
                                1. Modérateur
                                  Voir là
                                  grep "$USER" /etc/passwd | cut -d: -f5
                                  ;-))
                                  0
                              2. Modérateur
                                consulte man ps sur ton système
                                0
                                1. et bien sûr, mon login est toujours là, et non mon nom réel ! SAT a disparu, ouf!

                                  et j'ajoute pour ta gloire! l'alignement en sortie est nickel, ce que ne reflète pas ma capture d'écran : voici le vrai alignement à l'écran, en sortie:

                                  moi
                                  PID TT TIME COMMAND
                                  15144 ? 00:00:00 sshd
                                  15145 pts/1 00:00:00 bash
                                  15302 pts/1 00:00:00 sh
                                  15307 pts/1 00:00:00 ps
                                  toi
                                  PID TT TIME COMMAND
                                  15174 ? 00:00:00 sshd
                                  15175 pts/2 00:00:00 bash
                                  15299 pts/2 00:00:00 more

                                  la recherche continue

                                  a+
                                  0
                                  • 1
                                  • 2
                                  • 3