Rakefile에서 bash 명령 실행
.NET Framework에서 여러 bash
명령 을 실행하고 싶습니다 Rakefile
.
나는 내에서 다음을 시도했다. Rakefile
task :hello do
%{echo "World!"}
end
그러나 실행시 rake hello
출력이 없습니까? Rakefile에서 bash 명령을 어떻게 실행합니까?
참고 : 이것은 Rakefile 에서 bash 명령을 실행하는 방법을 구체적으로 묻는 것이므로 중복이 아닙니다 .
rake가 이것을 원하는 방식은 http://rubydoc.info/gems/rake/FileUtils#sh-instance_method 예 :
task :test do
sh "ls"
end
내장 rake 함수 sh는 명령의 반환 값을 처리하고 (명령에 0이 아닌 반환 값이있는 경우 작업이 실패 함) 추가로 명령 출력도 출력합니다.
Ruby에서 쉘 명령을 실행하는 방법에는 여러 가지가 있습니다. 간단한 방법 (가장 일반적인 방법)은 백틱을 사용하는 것입니다.
task :hello do
`echo "World!"`
end
백틱은 셸 명령의 표준 출력이 반환 값이되는 좋은 효과가 있습니다. 예를 들어 다음 ls
을 수행 하여 출력을 얻을 수 있습니다.
shell_dir_listing = `ls`
그러나 쉘 명령을 호출하는 다른 많은 방법이 있으며 모두 장점 / 단점을 가지며 다르게 작동합니다. 이 문서 에서는 선택 사항에 대해 자세히 설명하지만 다음은 간단한 요약 가능성입니다.
stdout = % x {cmd} -백틱에 대한 대체 구문, 배후에서 동일한 작업을 수행합니다.
exec (cmd) -실행중인 프로세스를 새 cmd 프로세스로 완전히 바꿉니다.
success = system (cmd) -하위 프로세스를 실행하고 성공 / 실패시 true / false 반환 (cmd 종료 상태 기준)
IO # popen (cmd) {| io | } -하위 프로세스를 실행하고 stdout 및 stderr를 io에 연결
stdin, stdout, stderr = Open3.popen3 (cmd) -하위 프로세스를 실행하고 모든 파이프에 연결 (in, out, err)
합의가 rake의 #sh
방법 을 선호하는 것처럼 보이지만 OP는 명시 적으로 bash를 요청하므로이 답변은 약간의 사용이있을 수 있습니다.
이것은 쉘 명령을 실행하기 Rake#sh
위해 Kernel#system
호출을 사용하기 때문에 관련이 있습니다. Ruby /bin/sh
는 사용자가 구성한 셸 또는 $SHELL
환경을 무시하고이를에 하드 코딩 합니다.
다음은에서 bash를 호출 /bin/sh
하여 sh
메서드 를 계속 사용할 수 있도록 하는 해결 방법입니다.
task :hello_world do
sh <<-EOS.strip_heredoc, {verbose: false}
/bin/bash -xeuo pipefail <<'BASH'
echo "Hello, world!"
BASH
EOS
end
class String
def strip_heredoc
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, ''.freeze)
end
end
#strip_heredoc
레일에서 차용 :
https://github.com/rails/rails/blob/master/activesupport/lib/active_support/core_ext/string/strip.rb
아마도 active_support를 요구하여 얻을 수 있거나 레일 프로젝트에있을 때 자동으로로드 될 수 있습니다. 그러나 저는이 외부 레일을 사용하고 있었기 때문에 직접 정의해야했습니다.
여기에는 마커가있는 외부 문서와 마커 EOS
가있는 내부 문서가 있습니다 BASH
.
이것이 작동하는 방식은 BASH 마커 사이의 내부 heredoc을 bash의 stdin에 공급하는 것입니다. 의 컨텍스트 내에서 실행 /bin/sh
되므로 루비가 아닌 posix heredoc입니다. 일반적으로 끝 표식이 열 1에 있어야하지만 들여 쓰기 때문에 여기에서는 그렇지 않습니다.
However, because it's wrapped within a ruby heredoc, the strip_heredoc
method applied there deindents it, placing the entirety of the left side of the inner heredoc in column 1 prior to /bin/sh
seeing it.
/bin/sh
also would normally expand variables within the heredoc, which could interfere with the script. The single quotes around the start marker, 'BASH', tell /bin/sh
not to expand anything inside the heredoc before it is passed to bash.
However /bin/sh
does still apply escapes to the string before passing it to bash. That means backslash escapes have to be doubled to make it through /bin/sh
to bash, i.e. \
becomes \\
.
The bash options -xeuo pipefail
are optional.
The -euo pipefail
arguments tell bash to run in strict mode, which stops execution upon any failure or reference to an undefined variable, even a command in a pipeline. This will return an error to rake, which will stop the rake task. Usually this is what you want. The arguments can be dropped if you want normal bash behavior.
The -x
option to bash and {verbose: false}
argument to #sh
work in concert so that rake only prints the bash commands which are actually executed. This is useful if your bash script isn't meant to run in its entirety, for example if it has a test which allows it to exit gracefully early in the script.
Be careful to not set an exit code other than 0 if you don't want the rake task to fail. Usually that means you don't want to use any || exit
constructs without setting the exit code explicitly, i.e. || exit 0
.
If you run into any bash weirdness along the way, turn off the -o pipefail
. I've seen a bit of bugginess related to it specifically when pipelining to grep
.
%{echo "World!"}
defines a String. I expect you wanted %x{echo "World!"}
.
%x{echo "World!"}
executes the command and returns the output (stdout). You will not see the result. But you may do:
puts %x{echo "World!"}
There are more ways to call a system command:
- Backticks: `
system( cmd )
popen
Open3#popen3
There are two ways:
sh " expr "
or
%x( expr )
Mind that ( expr ) can be { expr } , | expr | or ` expr `
The difference is, sh "expr" is a ruby method to execute something, and %x( expr ) is the ruby built-in method. The result and action are different. Here is an example
task :default do
value = sh "echo hello"
puts value
value = %x(echo world)
puts value
end
get:
hello # from sh "echo hello"
true # from puts value
world # from puts value
You can see that %x( expr )
will only do the shell expr but the stdout will not show in the screen. So, you'd better use%x( expr )
when you need the command result.
But if you just want to do a shell command, I recommend you use sh "expr"
. Because sh "irb"
will make you go into the irb shell, while %x(irb)
will dead.
참고URL : https://stackoverflow.com/questions/9796028/execute-bash-commands-from-a-rakefile
'Programing' 카테고리의 다른 글
SQL Server에서 int를 데이터 형식 숫자로 변환하는 산술 오버플로 오류가 발생하는 이유는 무엇입니까? (0) | 2020.11.13 |
---|---|
jquery에서이 날짜에서 일주일을 어떻게 빼나요? (0) | 2020.11.13 |
TLS 1.2를 사용하도록 .NET 웹 서비스 업데이트 (0) | 2020.11.13 |
문자열에 특수 문자가 포함되어 있는지 확인 (0) | 2020.11.13 |
Windows 일괄 처리에서 null 변수 확인 (0) | 2020.11.13 |