Question

Je suis tombé sur le problème suivant: J'écris un script bash Linux qui effectue les opérations suivantes:

  • Ligne de lecture de fichier
  • Bande le caractère \n de la fin de la ligne de lire
  • Exécuter la commande qui est là-dedans

Exemple: commands.txt

ls
ls -l
ls -ltra
ps as

L'exécution du fichier bash doit obtenir la première ligne, et l'exécuter, mais alors que le présent \n, le shell sorties juste « command not found: ls » Cette partie du script ressemble à ceci

 read line

        if [ -n "$line" ]; then #if not empty line

                #myline=`echo -n $line | tr -d '\n'`
                #myline=`echo -e $line | sed ':start /^.*$/N;s/\n//g; t start'`

                myline=`echo -n $line | tr -d "\n"`
                $myline  #execute it

                cat $fname | tail -n+2 > $fname.txt
                mv $fname.txt $fname
        fi

vous avez commenté les choses que j'ai essayé avant de demander SO. Toutes les solutions? Je briser mon cerveau pour les deux dernières heures au cours de cette ...

Était-ce utile?

La solution

Je aime toujours perl -ne 'chomp and print', pour tailler les nouvelles lignes. Nice et facile à retenir.

par exemple. ls -l | perl -ne 'chomp and print'

Cependant

Je ne pense pas que votre problème ici cependant. Bien que je ne suis pas sûr que je comprends comment vous passez les commandes dans le fichier à la « lire » dans votre script shell.

Avec un script de test de mon propre comme celui-ci (test.sh)

read line
if [ -n "$line" ]; then
  $line
fi

et un fichier d'entrée de l'échantillon comme cela (test.cmds)

ls 
ls -l
ls -ltra

Si je lance comme ça ./test.sh < test.cmds, je vois le résultat attendu, qui consiste à exécuter la première commande ls sur le répertoire de travail courant.

Peut-être votre fichier d'entrée a d'autres caractères non imprimables en elle?

le mien ressemble à ceci

od -c test.cmds 
0000000    l   s      \n   l   s       -   l  \n   l   s       -   l   t
0000020    r   a  \n                                                    
0000023

A partir de vos commentaires ci-dessous, je suppose que vous pouvez avoir des retours chariot ( « \ r ») dans votre fichier d'entrée, ce qui est la même chose que d'une nouvelle ligne. Le fichier d'entrée à l'origine au format DOS? Si oui, alors vous devez convertir la ligne DOS 2 octets fin « \ r \ n » à un seul octet UNIX, « \ n » pour atteindre les résultats escomptés.

Vous devriez être en mesure de le faire en échangeant le « \ n » pour « \ r » dans l'un de vos lignes commentées.

Autres conseils

Quelqu'un a déjà écrit un programme qui exécute des commandes shell: fichier sh

Si vous voulez vraiment que pour exécuter la première ligne d'un fichier: head -n 1 file |sh

Si votre problème est retour-chariot: tr -d '\r' <file |sh

J'ai essayé ceci:

read line
echo -n $line | od -x

Pour l'entrée 'xxxx', je reçois:

0000000 7878 7878

Comme vous pouvez le voir, il n'y a pas \n à la fin du contenu de la variable. Je suggère d'exécuter le script avec l'-x d'option (bash -x script). Cela affichera toutes les commandes quand elles sont exécutées.

[EDIT] Votre problème est que vous avez modifié commands.txt sous Windows. Maintenant, le fichier contient CRLF (0D0A) comme délimiteurs de ligne qui embrouille read (et ls\r n'est pas une commande connue). Utilisez dos2unix ou similaire pour le transformer en un fichier Unix.

Vous pouvez également essayer de remplacer les retours chariot avec des sauts de ligne utilisant uniquement builtins Bash:

line=$'a line\r' 
line="${line//$'\r'/$'\n'}" 
#line="${line/%$'\r'/$'\n'}"       # replace only at line end
printf "%s" "$line" | ruby -0777 -n -e 'p $_.to_s' 

vous avez besoin commande eval


#!/bin/bash -x

while read  cmd
do
 if [ "$cmd" ]
 then
  eval "$cmd"
 fi
done

Je l'ai couru comme
./script.sh

fichier.txt était:

ls
ls -l
ls -ltra
ps as

mais ne fonctionne pas pour ls, je recommande d'avoir un regard sur find 's' option -print0

Le script suivant fonctionne (au moins pour moi):

#!/bin/bash

while read I ; do if [ "$I" ] ; then $I ; fi ; done ;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top