Comment forcer la montre à s'exécuter sous bash

18

Le problème est que lorsque la montre est exécutée, elle s'exécute shet j'obtiens cette erreur:

sh: 1: func1: not found

voici le code:

#!/bin/bash

func1(){
  echo $1
}

export -f func1

watch func1
Rachid Oussanaa
la source
Pouvez-vous donner la commande que vous exécutez réellement?
cuonglm
@Gnouc au lieu d'echo $ 1 j'ai un script un peu long donc je ne sais pas ..
Rachid Oussanaa
Je veux dire, comment avez-vous exécuté votre commande ssh?
cuonglm
@Gnouc ./bin/myfunc.sh
Rachid Oussanaa

Réponses:

10

Ok, il y a donc quelques problèmes avec votre approche.

Vous exportez une fonction qui n'est pas portable entre les shells. watchexécute ses commandes avec /bin/sh, ce qui n'est pas le cas sur votre système bash. Et quel que soit le shell, il ne respecte pas les exportations de fonctions, vous obtenez donc l'erreur.

Deuxièmement, vous pouvez changer votre commande en quelque chose comme watch bash -c 'func1', mais cela peut ne pas bien fonctionner non plus.
La raison ici est que toutes les variables définies par le script ne seront pas disponibles pour la fonction. Vous pourriez être en mesure d'exporter ceux dont il a besoin, mais cela commence à devenir désordonné.

La solution la plus sûre est de mettre func1un script par lui-même et d'appeler ce script.
 

En bref, essayez:

watch bash -c func1
Patrick
la source
1
Il est très consommateur de CPU dans le cas où la fonction est définie dans.bash_profile
VarunAgw
@VarunAgw, c'est un bon point. Cependant, c'est une excellente commande pour surveiller les choses dans un environnement où le .bash_profilefichier est relativement vide. Cependant, je voulais exécuter un alias qui se trouvait dans mon .bash_aliasesfichier ( provenant de mon.bashrc ), j'ai donc fini par ajouter également l' -iindicateur à bash. J'ai pensé que cela pourrait aider quelqu'un:watch bash -ic "func1; alias1; func2; …"
aaiezza
Ne watch -x bash -c my-funcfonctionne que pour moi sur Ubuntu Server 16.04 - tandis que d'autres ne le font pas.
Nam G VU
14

Le shell par défaut pour watchest /bin/sh. Les shells n'hériteront pas des variables ou fonctions exportées d'autres types de shell.

Si votre système ne crée pas de lien symbolique /bin/shvers /bin/bash(ou votre shell actuel), vous pouvez demander watchd'exécuter votre shell en utilisant -xou --exec:

watch -x bash -c "my_func"

ou

watch --exec bash -c "my_func"

Ceci est différent de watch bash -c "test_watch"(à l'exclusion de --exec) car il n'utilise pas /bin/shpour générer le processus enfant (dans ce cas, bash), en le maintenant bashcomplètement. Comme indiqué dans d'autres réponses, cela peut devenir compliqué si vous exportez des fonctions fortement couplées à l'environnement actuel (c'est-à-dire nécessitant d'autres variables ou fonctions).


Un exemple:

test_watch() { echo 'Working!'; }
export -f test_watch
watch --exec bash -c "test_watch"

donne le familier

Every 2.0s: bash -c test_watch                                   Thu Mar 31 11:15:56 2016

Working!
Andy
la source
Seulement watch -x bash -c my-funcoui, cela fonctionne pour moi sur Ubuntu Server 16.04 - tandis que d'autres ne le font pas. Merci beaucoup!
Nam G VU
4

Pourquoi exécuter watchdepuis l'intérieur de votre script? Pourquoi ne pas avoir ce script shell:

$ cat func1 
#!/bin/bash

func1(){
  echo $1
}

func1 $1

... puis lancez-le comme ça ...

$ watch func1 foo
Cricket rouge
la source