Supposons que je dispose du script bash simple suivant que je souhaite soumettre à un serveur de traitement par lots via SLURM:
#!/bin/bash
#SBATCH -o "outFile"$1".txt"
#SBATCH -e "errFile"$1".txt"
hostname
exit 0
Dans ce script, je veux simplement écrire la sortie de hostname
sur un fichier texte dont je contrôle le nom complet via la ligne de commande, comme suit:
login-2:jobs$ sbatch -D `pwd` exampleJob.sh 1
Submitted batch job 203775
Malheureusement, il semble que mon dernier argument de ligne de commande (1) n’ait pas été analysé par sbatch, car les fichiers créés n’ont pas le suffixe recherché et la chaîne "$ 1" est interprétée littéralement:
login-2:jobs$ ls
errFile$1.txt exampleJob.sh outFile$1.txt
J'ai regardé des endroits dans DONC et ailleurs , mais je n'ai pas eu de chance. Ce que je recherche essentiellement, c’est l’équivalent du commutateur -v
de l’utilitaire qsub
dans les clusters activés par couple.
Edit: comme mentionné dans le fil de commentaire sous-jacent, j'ai résolu mon problème de manière très difficile: au lieu de n'avoir qu'un seul script qui serait soumis plusieurs fois au serveur de traitement par lots, chacun avec des arguments de ligne de commande différents, j'ai créé un "script principal" qui fait simplement écho et redirige le même contenu sur différents scripts, le contenu de chaque script étant modifié par le paramètre de ligne de commande passé. Ensuite, j'ai soumis tous ceux-ci à mon serveur de commandes par le biais de sbatch
. Toutefois, cela ne répond pas à la question initiale et j’hésite donc à l’ajouter comme réponse à ma question ou à indiquer que cette question est résolue.
Les lignes commençant par #SBATCH ne sont pas interprétées par bash mais remplacées par code par sbatch . Les options de sbatch ne supportent pas $ 1 vars (seulement% j et quelques autres, le remplacement de $ 1 par% 1 ne fonctionnera pas) .Quand vous n'avez pas de processus sbatch différents fonctionnant en parallèle, vous pouvez essayer
#!/bin/bash
touch outFile${1}.txt errFile${1}.txt
rm link_out.sbatch link_err.sbatch 2>/dev/null # remove links from previous runs
ln -s outFile${1}.txt link_out.sbatch
ln -s errFile${1}.txt link_err.sbatch
#SBATCH -o link_out.sbatch
#SBATCH -e link_err.sbatch
hostname
# I do not know about the background processing of sbatch, are the jobs still running
# at this point? When they are, you can not delete the temporary symlinks yet.
exit 0
Alternative: Comme vous l'avez dit vous-même dans un commentaire, vous pouvez créer un masterscript . Ce script peut contenir des lignes telles que
cat exampleJob.sh.template | sed -e 's/File.txt/File'$1'.txt/' > exampleJob.sh
# I do not know, is the following needed with sbatch?
chmod +x exampleJob.sh
Dans votre modèle, les lignes #SBATCH ressemblent à
#SBATCH -o "outFile.txt"
#SBATCH -e "errFile.txt"
Si vous passez vos commandes via la ligne de commande, vous pouvez réellement éviter le problème de l'impossibilité de passer des arguments de ligne de commande dans le script batch. Ainsi, par exemple, en ligne de commande:
var1="my_error_file.txt"
var2="my_output_file.txt"
sbatch --error=$var1 --output=$var2 batch_script.sh
L'utilisation d'un wrapper est plus pratique. J'ai trouvé cette solution de ce fil .
Le problème est que les directives SBATCH sont considérées comme des commentaires par le shell et que vous ne pouvez donc pas utiliser les arguments passés. Au lieu de cela, vous pouvez utiliser un document here pour alimenter votre script bash une fois les arguments définis.
Dans le cas de votre question, vous pouvez remplacer le fichier de script Shell par ceci:
#!/bin/bash
sbatch <<EOT
#!/bin/bash
#SBATCH -o "outFile"$1".txt"
#SBATCH -e "errFile"$1".txt"
hostname
exit 0
EOT
Et vous exécutez le script Shell comme ceci:
bash [script_name].sh [suffix]
Et les sorties seront sauvegardées dans outFile [suffixe] .txt et errFile [suffixe] .txt
Quelque chose comme ça marche pour moi et Torque
echo "$(pwd)/slurm.qsub 1" | qsub -S /bin/bash -N Slurm-TEST
slurm.qsub:
#!/bin/bash
hostname > outFile${1}.txt 2>errFile${1}.txt
exit 0