J'essaie de faire en sorte qu'applescript interagisse avec la boucle bash for qui fait partie de mon code pour éviter d'avoir à lister chaque hôte manuellement et d'exécuter des blocs tell / end tell individuels pour chaque hôte trouvé dans hosts2.txt
Le but du script est d'ouvrir un nouvel onglet de terminal sur mon Mac et de lancer automatiquement "screen -r $ HOST" dans chaque nouveau terminal jusqu'à la fin de la liste d'hôtes dans le document hosts2.txt. Chaque hôte est répertorié sur sa propre ligne.
J'ai essayé une boucle for tout compris, sans le code applescript "repeat 2 times" "end repeat" qui est montré ci-dessous. Il se répète 2 fois car il n'y a que 2 hôtes répertoriés dans le document texte à des fins de test. Chaque fois que j'ai une sortie d'erreur.
dev 44:52: syntax error: Expected end of line but found command name. (-2741) pulsar 44:52: syntax error: Expected end of line but found command name. (-2741)
Ce que j'attends, c'est que le code exécute l'ouverture de nouveaux onglets de terminal avec screen -r pour chaque hôte. La sortie d'erreur est en dessous de cette ligne.
#!/bin/bash for HOST in `cat ~/bin/hosts2.txt` do echo $HOST osascript -e 'repeat 2 times tell application "Terminal" activate tell application "System Events" to keystroke "t" using [command down] tell application "Terminal" to activate set host to $HOST tell application "Terminal" do shell script "screen -r " & host in front window end tell end repeat' done
3 Réponses :
Vous avez une faute de frappe dans votre code.
La ligne dire à l'application "Terminal" activer
devrait être dire à l'application "Terminal" d'activer
.
Le développement des variables ne fonctionne pas non plus entre guillemets simples dans bash (les guillemets simples signifient que tout est interprété littéralement), donc la ligne set host to $ HOST
entre les guillemets simples ne fonctionnera pas.
/ p>
Essayez ceci:
#!/bin/bash for HOST in `cat ~/bin/hosts2.txt` do echo $HOST osascript -e "repeat 2 times tell application \"Terminal\" to activate tell application \"System Events\" to keystroke \"t\" using [command down] tell application \"Terminal\" to activate set host to \"$HOST\" tell application \"Terminal\" do shell script \"screen -r \" & host in front window end tell end repeat" done
Edit: Je pense qu'il y a en fait un autre problème: lors de la définition d'une variable sur une chaîne dans applescript, la chaîne doit être incluse dans citations. Donc, set host sur $ HOST
provoque une erreur car il interprète la valeur de $ HOST
("pulsar" ou "dev") comme une commande qu'il est impossible de trouver / exécuter ; il doit être défini l'hôte sur \ "$ HOST \"
à la place. Je l'ai changé ci-dessus.
Ne générez PAS de code exécutable via une interpolation de chaîne brute. C'est extrêmement dangereux , par exemple voir toutes les attaques par injection SQL. Voici la bonne façon de passer des arguments dans un AppleScript. Apprenez-le, transmettez-le.
Vous trouverez peut-être un here-doc lisible et facile à utiliser. Utilisez également une boucle while-read pour parcourir les lignes d'un fichier (réf: http: // mywiki .wooledge.org / BashFAQ / 001 )
while read -r host; do echo "$host" osabody=$(cat << END_OSA repeat 2 times tell application "Terminal" to activate tell application "System Events" to keystroke "t" using [command down] tell application "Terminal" to activate set host to "$host" tell application "Terminal" do shell script "screen -r " & host in front window end tell end repeat END_OSA ) osascript -e "$osabody" done < ~/bin/hosts2.txt
La parenthèse de fin de la substitution de commande $ (cat ...
doit être sur un ligne car le mot de fin de l'hérédoc doit être les seuls caractères de cette ligne.
Il y a quelques problèmes avec votre script: certains l'empêchent de fonctionner complètement; certains qui lui font faire la mauvaise chose; et certains qui n'avaient pas besoin d'être là en premier lieu. Il y a quelques autres réponses qui abordent certains points, mais aucune d'elles n'a semblé tester le script car il y en a beaucoup qu'elles ne traitent pas.
... pour chaque hôte trouvé dans le fichier hosts2.txt ...
... Chaque hôte est répertorié sur sa propre ligne.
Alors cette ligne:
osascript <<OSA property home : system attribute "HOME" property file : POSIX file (home & "/bin/hosts2.txt") set hosts to read my file using delimiter {return, linefeed} repeat with host in hosts tell application "Terminal" to do script ("screen -r " & host) end repeat OSA
n'est pas ce que vous voulez. Cela créera un tableau à partir de mots individuels, pas de lignes dans le fichier. Vous souhaitez utiliser la commande read
, qui lit un fichier ligne par ligne. Vous pouvez structurer une boucle de cette manière:
while read -r HOST; do echo "$HOST" osascript -e "tell application \"Terminal\" to do script \"screen -r $HOST\"" done < ~/bin/hosts2.txt
Ensuite, il y a l'AppleScript lui-même.
Je ne sais pas pourquoi vous avez inclus une boucle repeat
.
Le but du script est d'ouvrir un nouvel onglet de terminal sur mon Mac et de lancer automatiquement "screen -r $ HOST" dans chaque nouveau terminal jusqu'à la fin de la liste d'hôtes dans le document hosts2.txt. Chaque hôte est répertorié sur sa propre ligne. Il se répète 2 fois car il n'y a que 2 hôtes répertoriés dans le document texte
Cela n'a aucun sens, étant donné que vous avez implémenté une boucle bash afin de lire les lignes dans la variable $ HOST
. Certes, vous lisiez des mots, pas des lignes, mais la répétition
AppleScript est un grattoir. Débarrassez-le.
Ensuite, vous avez ceci:
tell application "Terminal" to do script "screen -r $HOST"
C'est environ une infinité de fois le nombre que vous devez dire
Terminal à activer
.
Cette ligne:
tell application "Terminal" do shell script "screen -r " & host in front window end tell
générera une erreur pour deux raisons: premièrement, host
est considéré comme un nom existant de une propriété dans les ajouts standard d'AppleScript, vous ne pouvez donc pas la définir sur une nouvelle valeur; deuxièmement, il n'y a pas de guillemets autour de $ HOST
, donc il ne sera pas reconnu comme une chaîne. Mais, c'est juste pour votre apprentissage, car nous allons en fait nous débarrasser complètement de cette ligne.
Enfin:
set host to $HOST
est faux. do shell script
n'est pas une commande Terminal . C'est une commande appartenant aux ajouts standard d'AppleScript. Par conséquent, si le reste de votre code fonctionnait et qu'il arrivait à cette commande, Terminal n'exécuterait rien. Au lieu de cela, les scripts shell fonctionneraient en arrière-plan sans shell réel, donc ce n'est pas très bon pour vous.
La commande que vous recherchez est do script
. P >
Malheureusement, il semble que, dans High Sierra au moins, les commandes AppleScript pour créer de nouveaux onglets et fenêtres dans Terminal ne fonctionnent plus, donc je peux voir pourquoi vous avez eu recours aux Événements système pour créer un onglet comme vous l'avez fait. Heureusement, ce n'est pas nécessaire, et vos multiples commandes activate
ne le sont pas non plus: do script
exécutera automatiquement Terminal et exécutera un script dans un nouvel onglet en par défaut.
Par conséquent, la seule commande AppleScript dont vous avez besoin est la suivante:
tell application "Terminal" activate tell application "System Events" to keystroke "t" using [command down] tell application "Terminal" to activate
En mettant tout cela ensemble, voici le script hybride final:
while read -r HOST; do . . . done < ~/bin/hosts2.txt
Si vous vouliez prendre la boucle de bash et la mettre dans AppleScript à la place, vous pouvez le faire comme celui-ci, pour lequel j'utiliserai un heredoc ( ) pour simplifier l'utilisation des guillemets et faciliter la lisibilité:
for HOST in `cat ~/bin/hosts2.txt`
Très proche de ce que je souhaite que le script fasse dans votre révision "Final Script". La seule différence est que je veux qu'il ouvre de nouveaux onglets de terminal plutôt que de nouvelles fenêtres, ce que fait votre révision. Le raccourci Commande + T est utilisé dans mon code précédent pour ouvrir un nouvel onglet à chaque fois avant d'exécuter "screen -r $ HOST" Des suggestions?
Dans mon Terminal , il ouvre un nouvel onglet, ce qui signifie qu'il s'agit d'un paramètre que vous définissez dans l'application elle-même. Je vais donc jeter un œil dans les préférences et le configurer pour ouvrir de nouveaux onglets en faveur des fenêtres.
Question très bien composée avec de bonnes informations, bravo et merci. Question: quelle version de macOS utilisez-vous? De plus, si cela ne vous dérange pas, veuillez publier le contenu de votre fichier
~ / bin / hosts2.txt
.hosts2.txt contient uniquement les éléments suivants: dev pulsar Chacun sur sa propre ligne.
J'ai oublié de répondre à l'autre question. J'utilise Mojave.