Contenu | Rechercher | Menus

Annonce

Si vous avez des soucis pour rester connecté, déconnectez-vous puis reconnectez-vous depuis ce lien en cochant la case
Me connecter automatiquement lors de mes prochaines visites.

À propos de l'équipe du forum.

#1 Le 14/02/2011, à 11:01

archi02

Comment utilise t'on fopen() ?

Bonjour à tous,

Utilisateur averti d'Ubuntu, je me lance l'écriture de petits scripts. Le morceau de script suivant ne fonctionne pas, sauriez-vous m'aiguiller ?

#!/bin/bash
#include <stdio.h>

CFG_FILE=fopen(bla.txt,"r");
fseek(CFG_FILE,244,0);
CURRENT_LEVEL=fgetc(CFG_FILE);
fclose(CFG_FILE);
return CURRENT_LEVEL;

exit 0;
Erreur de syntaxe près du symbole inattendu « ( »

C'est finalement le contenu du message d'erreur (qui pointe sur la ligne fopen) qui me laisse perplexe...

Hors ligne

#2 Le 14/02/2011, à 11:19

Mathieu147

Re : Comment utilise t'on fopen() ?

C'est quel langage, ça?

Pourquoi mettre #include <stdio.h> si c'est du Bash? Et si c'est du C, pourquoi mettre #!/bin/bash?

Sinon, il faut au moins mettre ton nom de fichier entre guillemets.


Pffff…

Hors ligne

#3 Le 14/02/2011, à 11:36

archi02

Re : Comment utilise t'on fopen() ?

Pardon oui, c'est du bash. Pourquoi mettre un include ? Je ne sais pas... c'est inutile ? C'est la première fois que je fais un script avec des fonctions externes comme celles-ci... ok, j'enlève donc. Et ok aussi pour le nom de fichier. Merci pour ta réponse, mais... le message d'erreur persiste ! smile

Pour tout dire, en effet, pour ce script, je m'inspire d'un script C... c'est pour cela qu'il y a des résidus.

Hors ligne

#4 Le 14/02/2011, à 12:30

ehmicky

Re : Comment utilise t'on fopen() ?

Salut,
Ton script mélange du Bash et du C :
  - Bash : déclaration des variables sans type, pas de main, exit 0, shabang, pas de compilation (il semble).
  - C : utilisation de fonctions C telles que fopen(), #include.
Tu peux pas mélanger du Bash et du C comme ça, ce sont des langages différents. Tu peux par contre compiler un fichier source en C, et exécuter le fichier créé dans un script en Bash (wrapper).
Les fonctions que tu trouvent dans man 2 et man 3 sont des fonctions C, celles que tu trouves dans man 1 des commandes Unix utilisables dans un script Bash.

Sinon, tu n'as pas besoin de passer par du C pour le programme que tu cherches à faire :

head -c244 bla.txt | tail -c1

ou en full-bash :

read -N244 <bla.txt ; echo "${REPLY: -1}"

Dernière modification par ehmicky (Le 14/02/2011, à 12:43)


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#5 Le 14/02/2011, à 12:41

archi02

Re : Comment utilise t'on fopen() ?

Super, merci pour cette réponse éclairante.

Techniquement, cela signifie que je ne peux utiliser la fonction fopen() en bash ? Pourtant d'après ce que je peux lire ici, il semblerait que si.
Et pour le exit 0;, il est indiqué ici, que c'est nécessaire.

Mais je veux bien croire que j'ai écris des hérésies du point de vue syntaxique, surtout qu'en effet j'ai un peu mélangé les deux langages sans trop m'en soucier. Mais lesquelles ?

EDIT : je viens de voir la dernière partie de ton message. Merci beaucoup, je regarde ça !

Dernière modification par archi02 (Le 14/02/2011, à 12:42)

Hors ligne

#6 Le 14/02/2011, à 12:56

ehmicky

Re : Comment utilise t'on fopen() ?

Non justement ton lien indique que mettre "exit 0" à la fin du programme est utilisé en Bash pas en C. Bien entendu, Bash et C utilisent tous deux exit et return, mais pour clore le programme principal, on utilise en général exit 0 en Bash et return en C, c'est pourquoi je disais que ton script utilisait là une syntaxe "Bash-like" mélangée avec d'autres éléments "C-like".
Sinon, le premier lien que tu indiques ne dis pas que tu peux utiliser fopen() directement dans un script Bash. Il s'agit de la man page de fopen() et comme toutes les man pages de la 2ème et 3ème section, elle parlent de fonctions C.
D'ailleurs, c'est simple, en Bash, tu utilises pas de parenthèses pour exécuter une fonction et lui passer des arguments :
- Bash : fonction/commande arg1 arg2
- C : fonction(arg1, arg2)

Le C est compilé : tu écris un source, tu le passe à la moulinette dans un compilateur comme gcc et ça te donne un fichier que tu peux éxécuter par exemple dans un terminal ou un script Bash.
Le Bash est interprété : tu écris un source, et tu le donnes à manger au programme /bin/bash, qui va exécuter des actions directement en fonction de ce que tu lui donnes.
Tu peux pas mélanger comme ça deux langages. Par contre, il y a plusieurs manières pour faire coopérer les deux langages : par exemple, tu peux écrire et compiler un fichier 100% en C, et l'exécuter dans un script Bash ; ou tu peux exécuter un script 100% Bash dans un programme à C via par exemple la fonction system()

Dernière modification par ehmicky (Le 14/02/2011, à 13:02)


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#7 Le 14/02/2011, à 13:31

archi02

Re : Comment utilise t'on fopen() ?

Effectivement, merci pour ces longues explications.
Donc fopen() est une fonction C, et ce n'est donc pas du tout dans mes compétences. Il me faut une solution 100% bash.

Les propositions (au dessus) iraient surement pour un fichier texte basique, mais dans ce cas j'essaye de lire une configuration dans "/sys/devices/pci0000:00/0000:00:02.0/config", t je n'obtiens rien d'exploitable. Il semblerait que ce soit plus un flux, d'un fichier texte...

En tout cas, il semblerait surtout que je m'attaque à quelque chose de bien trop complexe pour mon maigre niveau. Ceci n'a pas été vain, mes connaissances ont fait un bon en te lisant. smile

Hors ligne

#8 Le 14/02/2011, à 13:53

ehmicky

Re : Comment utilise t'on fopen() ?

En fait, le fichier config dont tu parles est un fichier texte régulier. Les "fluxs" sont par exemple les special files, les named pipes ou les sockets, mais ces fluxs peuvent d'ailleurs eux aussi être traités comme s'il s'agissait de fichiers textes, c'est l'un des principes de la "philosophie Unix" (tout est fichier).
Dans ton cas je pense que ton problème vient du fait que /sys/devices/pci0000\:00/0000\:00\:02.0/config contient des caractères non-imprimables. Par exemple, si je fais :

head -c244 /sys/devices/pci0000\:00/0000\:00\:02.0/config | tail -c1

je tombe sur un nul, '\0' (caractère ASCII numéro 0, représentant "rien" et n'imprimant donc rien), du coup rien n'est imprimé. Tu peux voir le numéro du caractère obtenu sous forme graphique avec :

head -c244 /sys/devices/pci0000\:00/0000\:00\:02.0/config | tail -c1 | od -cAn

ou décimale :

head -c244 /sys/devices/pci0000\:00/0000\:00\:02.0/config | tail -c1 | od -tu1 -An

Après, que veux-tu faire avec ce caractère, l'utiliser comme un nombre ou comme un caractère ?


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#9 Le 14/02/2011, à 14:34

ehmicky

Re : Comment utilise t'on fopen() ?

Un exemple pour coordonner Bash et C :
Un fichier "numero.c" en C :

#include    <stdio.h>
#include    <stdlib.h>

int main(int argc, char *argv[])
{
    if ( argc <= 2 )
    {
        fprintf(stderr, "Erreur : Usage : numero FICHIER OFFSET\n");
        exit(1);
    }

    FILE *Fichier;
    int Caractere;
    long int Offset = strtol(argv[2], NULL, 10);

    if ( ( Fichier = fopen(argv[1], "r") ) == NULL )
    {
        perror("Impossible d'ouvrir le fichier");
        exit(1);
    }
    if ( fseek(Fichier, Offset, SEEK_SET) )
    {
        perror("Impossible de lire le fichier");
        exit(1);
    }
    if ( ( Caractere = fgetc(Fichier) ) == EOF )
    {
        fprintf(stderr, "Erreur : fin du fichier atteinte");
        exit(1);
    }

    printf("%d\n", Caractere);

    if ( fclose(Fichier) )
    {
        perror("Impossible de fermer le fichier");
        exit(1);
    }
    return EXIT_SUCCESS;    
}

compilé avec :

gcc -Wall -W -o numero numero.c

Ensuite, tu utilises la commande "numero" produite dans un script Bash :

#!/bin/bash 

if ! Nombre="$(/chemin/vers/numero "/sys/devices/pci0000:00/0000:00:02.0/config" 244)"
then
    echo "Erreur" >&2
    exit 1
fi
echo "$Nombre"

ou un terminal :

$ /chemin/vers/numero fichier offset
resultat

Dernière modification par ehmicky (Le 14/02/2011, à 15:01)


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#10 Le 14/02/2011, à 15:22

archi02

Re : Comment utilise t'on fopen() ?

Woaw... que de détails ! smile

En fait, quand je tape la commande ci dessous, je modifie le contraste de mon écran en attribuant une valeur hexa comprise entre 00 et FF (ici : 55).

sudo setpci -s 00:02.0 f4.b=55

Je sais que le fichier modifié est celui indiqué dans mon post précédent, la valeur hexa correspondant aux deux derniers caractères d'une première ligne de 244 caractères (enfin je crois).

Je cherche simplement à récupérer la valeur actuellement écrite dans le fichier (et donc ainsi savoir quel est le niveau de contraste actuellement en cours). Cette valeur sera dans ce script utilisée en tant que nombre afin de l'incrémenter ou le décrémenter d'un pas (et ainsi régler le contraste).

(Merci pour les exemples d'inclusion entre bash et C)

Dernière modification par archi02 (Le 14/02/2011, à 15:23)

Hors ligne

#11 Le 14/02/2011, à 15:54

ehmicky

Re : Comment utilise t'on fopen() ?

Essaye :

Contraste="$(setpci -s 00:02.0 f4.b)"
Augmentation=16
NouveauConstraste="$(printf "%x\n" $(( 0x$Contraste + $Augmentation )))"
setpci -s 00:02.0 f4.b=$NouveauConstraste

Augmentation est en décimal ici.


Stego++, bibliothèque libre de stéganographie (avec cryptographie), à venir !
Besoin de votre aide :
Stats sur les compilateurs C++ les plus utilisés
Comment utiliser les archetypes C++ ?

Hors ligne

#12 Le 14/02/2011, à 16:08

archi02

Re : Comment utilise t'on fopen() ?

Arf... comment dire... fantastique ? Mieux encore ?
Comment deviner qu'il suffisait de réutiliser la commande 'setpci' pour tout simplement afficher la valeur en question ? Évidemment, en ce cas, plus besoin de fopen() et cie... et comble du travail bien fait, tu me donnes les lignes "prêtes à coder" ! La grande classe. cool

Ça c'est de l'entraide ! Bravo et merci à toi ehmicky !

Hors ligne