简体   繁体   中英

Filepaths issue in ruby script using ssh-net

I am currently writing a ruby script to allow me to upload .war files into a VPC. To update a java service in our cloud I simply build with maven locally and replace the .war file in the VPC with the file I have created via the build. My problem lies in my file paths in my script. It seems that when even trying to run simple bash commands such as 'mv', or 'rm' I am presented with the following error -

mv: missing destination file operand after `/tmp/asset-manager-service-1.0.2-SNAPSHOT.war'
Try `mv --help' for more information.
bash: line 1: /srv/asset-manager-service/war/: Is a directory

I thought that maybe this may be a problem with the fact I have a variable just before the second mv directory? The same error applies when I try to use 'rm' as well. I am new to ruby, so this may not be pretty, but here is some of the code in question.

#handles the old war file and pushes up the new one.
  def handle_war(value)
    war_file_name = File.basename("#$warfile")
    local_war_path = File.absolute_path("#$warfile")
    puts File.exist?(local_war_path)
    remote_war_path = "/tmp/#{war_file_name}"

    puts "IP is " + value
    puts "CONNECTING to ubuntu@#{value}.."
    Net::SSH.start("#{value}", "ubuntu") do |ssh|
      puts 'Connected.'
      puts "SENDING #{local_war_path} to VPC /tmp folder - #{remote_war_path}"
      ssh.sftp.upload!('asset-manager-service-1.0.2-SNAPSHOT.war',
                       remote_war_path)

      print "SENT - New .war created at /tmp/#{war_file_name}"

      old_war_file = ssh.exec!("ls /srv/#{$service_dir}/war/*war")
      old_war_file_name = File.basename(old_war_file)
      puts 'What do you want to do with this old war file? - (delete/backup)'
      puts old_war_file
      input = gets.chomp
      if input=='delete'
        puts ssh.exec!("sudo rm #{old_war_file}")
        puts 'If no errors thrown - old .war file deleted successfully.'
      elsif input == 'backup'
        puts ssh.exec!("sudo mv #{old_war_file} srv/#$service_dir/war_backup/#{old_war_file_name}")
        puts 'If no errors thrown - old .war file backed up successfully at'
        puts "srv/#$service_dir/war_backup/#{old_war_file_name}"
      else
        puts 'no valid option chosen. Leaving .war file as is. You will have to delete or backup the .war manually.'
      end

      puts "MOVING the new war file from tmp into #{$service_dir}/war directory"
      puts ssh.exec!("sudo mv /tmp/#{war_file_name} /srv/#{$service_dir}/war/")
      puts 'done!'
    end
  end

The main issue here I think is that there seems to be some funny business when I use variables as part of the filepaths.. I am unsure as to why this should make any difference though.I understand this question may be a bit hard to grasp out of context but I am really banging my head here. Long story short -

  1. Do filepaths change when using File.basename?
  2. Is there a difference from using a variable in a filepath as opposed to a hard coded string?
  3. Are there any glaring mistakes in my code that could be the problem?

It would appear that war_file_name has a newline at the end of it.

That would cause the shell to see

sudo mv /tmp/#{war_file_name} /srv/#{$service_dir}/war/

as

sudo mv /tmp/#{war_file_name}
/srv/#{$service_dir}/war/

which would give both the mv missing destination error and the "is a directory" error from the shell trying to execute a directory as a command.

(In general you don't want to use the output from ls for any scripting work as it is unreliable and unsafe in many cases. In this case the output from echo would work just as well for example, though would still have many/all of the safety problems with "odd" filenames. Working around those issues would require some more scripting but is doable.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM