Angesichts der Tatsache, dass der Konsens die #shMethode von Rake zu bevorzugen scheint , OP jedoch ausdrücklich Bash anfordert, kann diese Antwort von Nutzen sein.
Dies ist relevant, da Rake#shder Kernel#systemAufruf zum Ausführen von Shell-Befehlen verwendet wird. Ruby codiert das fest /bin/shund ignoriert dabei die konfigurierte Shell des Benutzers oder $SHELLdie Umgebung.
Hier ist eine Problemumgehung, mit der bash aufgerufen wird /bin/sh, sodass Sie die shMethode weiterhin verwenden können :
task :hello_world do
sh <<-EOS.strip_heredoc, {verbose: false}
/bin/bash -xeu <<'BASH'
echo "Hello, world!"
BASH
EOS
end
class String
def strip_heredoc
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, ''.freeze)
end
end
#strip_heredoc wird von Schienen ausgeliehen:
https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/string/strip.rb
Sie könnten es wahrscheinlich erhalten, indem Sie active_support benötigen, oder es wird automatisch geladen, wenn Sie sich in einem Rails-Projekt befinden, aber ich habe diese externen Rails verwendet und musste es daher selbst definieren.
Es gibt zwei Heredocs, einen äußeren mit den Markern EOSund einen inneren mit den Markern BASH.
Die Art und Weise, wie dies funktioniert, besteht darin, den inneren Heredoc zwischen den BASH-Markern dem Bash-Standard zuzuführen. Beachten Sie, dass es im Kontext von ausgeführt wird/bin/sh , es ist also ein Posix Heredoc, kein Ruby. Normalerweise muss sich die Endmarkierung in Spalte 1 befinden, was hier aufgrund des Einrückens nicht der Fall ist.
Da es jedoch in einen Rubin-Heredoc eingewickelt ist, wird es durch die dort strip_heredocangewandte Methode entfernt und die gesamte linke Seite des inneren Heredocs in Spalte 1 platziert, bevor es /bin/shangezeigt wird.
/bin/shwürde normalerweise auch Variablen innerhalb des Heredocs erweitern, was das Skript stören könnte. Die einfachen Anführungszeichen um den Startmarker 'BASH' weisen darauf hin, dass /bin/shim Heredoc nichts erweitert werden soll, bevor es an bash übergeben wird.
Wendet /bin/shjedoch immer noch Escapezeichen auf die Zeichenfolge an, bevor sie an bash übergeben wird. Das bedeutet, dass Backslash-Fluchten verdoppelt werden müssen, um /bin/shzu Bash zu gelangen, dh \zu werden\\ .
Die Bash-Optionen -xeusind optional.
Die -euArgumente weisen bash an, im strengen Modus ausgeführt zu werden, wodurch die Ausführung bei einem Fehler oder Verweis auf eine undefinierte Variable gestoppt wird. Dies gibt einen Fehler an Rake zurück, wodurch die Rake-Task gestoppt wird. Normalerweise ist dies das, was Sie wollen. Die Argumente können gelöscht werden, wenn Sie ein normales Bash-Verhalten wünschen.
Die -xOption zum Bash und {verbose: false}Argumentieren, um gemeinsam zu #sharbeiten, sodass Rake nur die Bash-Befehle druckt, die tatsächlich ausgeführt werden. Dies ist nützlich, wenn Ihr Bash-Skript nicht vollständig ausgeführt werden soll, z. B. wenn es einen Test enthält, mit dem es ordnungsgemäß im Skript beendet werden kann.
Achten Sie darauf, keinen anderen Exit-Code als 0 festzulegen, wenn die Rake-Task nicht fehlschlagen soll. Normalerweise bedeutet dies, dass Sie keine || exitKonstrukte verwenden möchten, ohne den Exit-Code explizit festzulegen, d || exit 0. H.
%{so%x(, und das gibt stdout als Zeichenfolge zurück, anstatt es zu drucken.