Append text in a file
wonderer007 opened this issue · 4 comments
wonderer007 commented
I am trying to append text at the bottom of a file with
execute(:printf, "%s\n%s\n", "hello", "world", ">>", "schedule.rb")
This produce error
(Backtrace restricted to imported tasks)
cap aborted!
SSHKit::Runner::ExecuteError: Exception while executing as deploy@139.59.138.154: printf exit status: 127
printf stdout: Nothing written
printf stderr: bash: line 1: fg: no job control
bash: line 2: hello: command not found
SSHKit::Command::Failed: printf exit status: 127
printf stdout: Nothing written
printf stderr: bash: line 1: fg: no job control
bash: line 2: hello: command not found
Tasks: TOP => deploy:restart => deploy:staging_files
(See full trace by running task with --trace)
The deploy has failed with an error: Exception while executing as deploy@139.59.138.154: printf exit status: 127
printf stdout: Nothing written
printf stderr: bash: line 1: fg: no job control
bash: line 2: hello: command not found
Is there any alternative to it ? Thanks!
leehambley commented
GitHub is not used for support, please ask your question at StackOverflow where the community can support you better.
bretweinraub commented
Here's an example of me appending to a file [straight in SSHKit]:
def test
SSHKit::Backend::Netssh.configure do |ssh|
ssh.ssh_options = {
user: 'myuser' # since we will be using execute() without mappings, we must set our user in this way. Thus your unmapped commands will not inherit as() blocks. See the README.
}
SSHKit.config.output_verbosity= Logger::DEBUG
end
on(ip_address) do
as(:myuser) do
execute(:touch,"/tmp/foo") # first arg is a symbol, so the command is mapped. See the README.md
execute("echo bar >> /tmp/foo") # first arg is a string, so command is not mapped AND is fed straight to the shell
end
end
end
end
@leehambley - does that look right?
leehambley commented
That looks correct @bretweinraub
bretweinraub commented
Here's a version without side-effects.
I'm gettting some mileage out of this. Seems like it is probably not thread safe, but useful if you are going to be using un-mapped executes()s and need them to run as a particular user:
# run a sshkit command as user [not using as() mappings, as you cant do complex shell magic in those]
def sshkit_as_user(user)
cached_user = SSHKit::Backend::Netssh.configure { | ssh | puts ssh.ssh_options[:user]} || `whoami`.chomp
begin
SSHKit::Backend::Netssh.configure do |ssh|
ssh.ssh_options = {
user: user
}
end
yield
ensure
SSHKit::Backend::Netssh.configure do |ssh|
ssh.ssh_options = {
user: cached_user
}
end
end
end
So the above becomes:
sskit_as_user(:myuser) do
on(ip_address) do
execute(:touch,"/tmp/foo") # first arg is a symbol, so the command is mapped. See the README.md
execute("echo bar >> /tmp/foo") # first arg is a string, so command is not mapped AND is fed straight to the shell
end
end