2010-08-28 6 views
8

J'essaie de lire les commandes à partir d'un fichier texte et d'exécuter chaque ligne à partir d'un script bash.exec line from file in bash

#!/bin/bash 
while read line; do 
    $line 
done < "commands.txt" 

Dans certains cas, si $line contient des commandes qui sont destinés à fonctionner en arrière-plan, par exemple command 2>&1 & ils ne démarreront pas en arrière-plan, et se déroulera dans le contexte actuel de script.

N'importe quelle idée pourquoi?

+3

Y a-t-il une raison pour laquelle vous ne pouvez pas faire "source commands.txt" au lieu d'écrire votre propre boucle? –

+0

que fait "source"? J'essaie de le tester maintenant – Quamis

+0

Veuillez consulter [BashFAQ/050] (http://mywiki.wooledge.org/BashFAQ/050). Ensuite, utilisez 'source' (ou' .') comme le suggère Jim Lewis. 'source' fait à peu près ce que dit la première phrase de votre question. –

Répondre

7

Si toutes vos commandes se trouvent dans "commands.txt", vous pouvez l'appeler un script shell. C'est pourquoi vous pouvez soit le trouver, soit l'exécuter normalement, c'est-à-dire chmod u + x, puis l'exécuter en utilisant sh commands.txt

1

Je n'ai rien à ajouter à la réponse de ghostdog74 sur la bonne façon de procéder, mais je peux expliquer pourquoi il échoue: Le shell analyse les redirections E/S, arrière-plan, et un tas d'autres choses avant qu'il ne l'expansion variable, donc au moment où $line est remplacé par command 2>&1 & il est trop tard pour reconnaître 2>&1 et & comme tout autre que les paramètres à command.

Vous pouvez améliorer cela en utilisant eval "$line" mais même là vous rencontrerez des problèmes avec les commandes multilignes (par exemple en boucle, si des blocs, etc.). Les approches source et sh n'ont pas ce problème.