441

I know it is not recommended, but is it at all possible to pass the user's password to scp?

I'd like to copy a file via scp as part of a batch job and the receiving server does, of course, need a password and, no, I cannot easily change that to key-based authentication.

DennisLi
  • 3,915
  • 6
  • 30
  • 66
Argelbargel
  • 5,840
  • 2
  • 23
  • 16
  • 2
    See also (later) question: http://stackoverflow.com/questions/1462284/how-to-respond-to-password-prompt-when-using-scp-in-a-shell-script where one answer mentions another possible way to do this. (NB: this is not a duplicate question - it is the original which the other duplicates.) – Jonathan Leffler Sep 22 '09 at 20:50
  • _Very_ closely related: [Pass a password to ssh in pure bash](https://stackoverflow.com/questions/24454037/pass-a-password-to-ssh-in-pure-bash/24455773#24455773) – Gabriel Staples Nov 09 '21 at 02:17
  • Instead of login via scp and copy, you can first setup a master connection with ssh, then run scp to copy the file via the master connection, without password. See https://unix.stackexchange.com/a/2869/17823 – ryenus May 29 '22 at 03:57

22 Answers22

724

Use sshpass:

sshpass -p "password" scp -r user@example.com:/some/remote/path /some/local/path

or so the password does not show in the bash history

sshpass -f "/path/to/passwordfile" scp -r user@example.com:/some/remote/path /some/local/path

The above copies contents of path from the remote host to your local.

Install :

  • ubuntu/debian
    • apt install sshpass
  • centos/fedora
    • yum install sshpass
  • mac w/ macports
    • port install sshpass
  • mac w/ brew
    • brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb
jbaums
  • 27,115
  • 5
  • 79
  • 119
KevinS
  • 8,087
  • 2
  • 17
  • 9
  • 1
    This recently saved me a lot of trouble on a project, thanks :) – Elliott Apr 12 '13 at 00:37
  • 20
    On Ubuntu 12.04 it only worked for me with single quotes over the password (e.g. 'password' instead of "password"). – odedfos Feb 06 '14 at 15:32
  • 7
    @odedfos, yes you need to use single quotes because some password generated chars can have a special interpretation in double quoted string interpolation – TerryE Jul 19 '14 at 12:50
  • 7
    This is how you install sshpass `apt-get install sshpass` – Jan-Terje Sørensen Aug 21 '14 at 06:05
  • 6
    On CentOS it's `yum -y install sshpass` – jgritty Aug 28 '14 at 23:05
  • 1
    `sudo port install sshpass` if you have [macports](https://www.macports.org/) on a mac – kdauria Dec 03 '14 at 03:39
  • 26
    The most secure way to do this is with a password *file*, like this: `sshpass -f `passwdfile` scp [...]`. This way, the password won't show up in `ps` listings, etc. and you can protect the password with file permissions. – Christopher Schultz Mar 20 '15 at 15:30
  • 2
    On OSX `brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb` – Abram May 25 '16 at 18:40
  • 4
    `scp` shows progress when not using `sshpass`. Is it possible to get that back? – Daniel Jul 13 '17 at 02:09
  • Best answer: note it also works with ssh (`sshpass -p pass ssh 'command'`) – рüффп Jun 06 '18 at 09:07
  • 3
    It works, but the console output from `scp` is hidden. – Jim Fell Feb 15 '19 at 16:53
  • The url for macOS has changed to: brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb – neowinston Feb 28 '20 at 15:47
  • On Debian didn't work for me with `-f "filename"` until I removed quotes around the file name, i.e.: `sshpass -f /path/to/passwordfile scp -r user@example.com:/some/remote/path /some/local/path` – rshev Sep 27 '20 at 18:45
  • 1
    In case if you observe a strict host key check error then you can add -o with `StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null` options. The complete example is as follows `sshpass -p "password" scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@domain-name.com:/tmp/from/psoutput /tmp/to/psoutput` – Sachin Rastogi Dec 02 '20 at 15:50
  • 1
    `brew install https://raw.githubusercontent.com/kadwanev/bigboybrew/master/Library/Formula/sshpass.rb` no longer works @jbaums > Error: Non-checksummed download of sshpass formula file from an arbitrary URL is unsupported! `brew extract` or `brew create` and `brew tap-new` to create a formula file in a tap on GitHub instead. – WurmD Dec 16 '21 at 22:59
67

just generate a ssh key like:

ssh-keygen -t rsa -C "your_email@youremail.com"

copy the content of ~/.ssh/id_rsa.pub and lastly add it to the remote machines ~/.ssh/authorized_keys

make sure remote machine have the permissions 0700 for ~./ssh folder and 0600 for ~/.ssh/authorized_keys

mustafaturan
  • 2,171
  • 21
  • 17
  • 71
    As I wrote: No, I cannot easily switch to key-based authentication. – Argelbargel Mar 09 '12 at 12:53
  • 3
    Do you mean .authorized_keys rather than . authorization_keys? – ABCD Apr 23 '15 at 08:06
  • 2
    A valid use for this would be a bash script that does multiple scp/ssh calls to a server where you want to ask the user for the password for the remote server. The password will then not show in history and you still have the befit of challenging for the password... but only once. I don't want to use a key file because I want to still authenticate the script user. – Wes Grant Aug 27 '15 at 19:45
  • 2
    Another valid use would be if you cannot easily enable key-based authentication on the target. Example: One of the main NAS producers - Synology with their DSM 6.0 - does not support it even in 2016. Sure, you could mess with configuration files and hope an update won't just overwrite it again (updating DSM frequently does break custom modifications). Sometimes - especially when the OP expressly writes they're already aware it's not optimal - people just need a solution. – Aaa Jun 03 '16 at 17:14
  • 6
    You should use `ssh-copy-id -i ~/.ssh/id_rsa.pub ` to copy the key on the remote server – alexandre-rousseau Nov 29 '18 at 09:24
  • @RousseauAlexandre do you mean "onto" or "to" the remove server? This answer is shocking, should it not be your_user@server ? – mckenzm Jun 07 '19 at 03:31
  • @mckenzm `ssh-copy-id` copy the public key from your local to the server. You should try `man ssh-copy-id` to get more information about this command. – alexandre-rousseau Jun 07 '19 at 12:40
  • apologies, I mixed my comments. I did not mean to say your comment was shocking, I should have separated these to show the answer above it was surprising. – mckenzm Jun 07 '19 at 23:52
  • 1
    Come on, anyone can find out how to generate SSH keys, the question is obviously not about that. Not everyone has complete control over every computer that they connect to. – Andrew Koster Mar 17 '20 at 05:38
  • This doesn't work for remote machines which are embedded Linux devices which have read-only file-systems, since you can't write anything to `~/.ssh/authorized_keys` on the target device. – Gabriel Staples Nov 09 '21 at 01:21
  • ssh-keygen will generate two files: id_rsa.pub,id_rsa. then put id_rsa.pub to remote server [USER]/.ssh/ and rename it to authorized_keys or just copy the content of id_rsa.pub in to authorized_keys on the remote server. and at the client, use the scp's "i" option to specify the id_rsa file. then you can use scp without to input the password – jack jin Nov 29 '21 at 08:35
60

If you are connecting to the server from Windows, the Putty version of scp ("pscp") lets you pass the password with the -pw parameter.

This is mentioned in the documentation here.

Haldean Brown
  • 12,411
  • 5
  • 43
  • 58
gWay
  • 1,087
  • 9
  • 7
49

curl can be used as a alternative to scp to copy a file and it supports a password on the commandline.

curl --insecure --user username:password -T /path/to/sourcefile sftp://desthost/path/
MBerg
  • 491
  • 4
  • 4
  • 1
    It quite slower than 'scp' but it does the job fine. – Victor May 29 '18 at 06:15
  • I found this to be faster when the destination is configured with a huge password prompt delay. `scp` has to wait 30+ seconds to let me put in a password, but `curl` worked immediately. – Ghost8472 Sep 10 '18 at 22:02
  • @Ghost8472 configured yes, but sometimes this delay is resolving the hostname, and also happens for sftp. – mckenzm Jun 07 '19 at 03:35
  • 4
    I got "curl: (1) Protocol "sftp" not supported or disabled in libcurl" – lobotmcj Feb 06 '20 at 20:34
  • I got an error saying that curl doesn't recognize -T as a parameter. – Andrés Marafioti Oct 28 '21 at 09:25
  • Invoke-WebRequest : Parameter cannot be processed because the parameter name 'T' is ambiguous. Possible matches include: -TimeoutSec -TransferEncoding. At line:1 char:40 + curl --insecure --user andres:notmypassword -T nottheserver:/home/andr ... + ~~ + CategoryInfo : InvalidArgument: (:) [Invoke-WebRequest], ParameterBindingException + FullyQualifiedErrorId : AmbiguousParameter,Microsoft.PowerShell.Commands.InvokeWebRequestCommand – Andrés Marafioti Oct 28 '21 at 09:26
  • @AndrésMarafioti look like you call Invoke-WebRequest from powershell this can does not work the same as curl. To my knowledge is does not support sftp or uploads – MBerg Oct 28 '21 at 12:35
  • The curl method, above, works when shell access is not allowed on the account. e.g. "Shell access is not enabled on your account!" – ravenshill May 18 '23 at 20:41
43

You can script it with a tool like expect (there are handy bindings too, like Pexpect for Python).

joelittlejohn
  • 11,665
  • 2
  • 41
  • 54
Pat Notz
  • 208,672
  • 30
  • 90
  • 92
25

You can use the 'expect' script on unix/terminal

For example create 'test.exp' :

#!/usr/bin/expect
        spawn scp  /usr/bin/file.txt root@<ServerLocation>:/home
        set pass "Your_Password"
        expect {
        password: {send "$pass\r"; exp_continue}
                  }

run the script

expect test.exp 

I hope that helps.

Prabhjeet
  • 261
  • 3
  • 4
10

You may use ssh-copy-id to add ssh key:

$which ssh-copy-id #check whether it exists

If exists:

ssh-copy-id  "user@remote-system"
RomanHotsiy
  • 4,978
  • 1
  • 25
  • 36
Shen JI
  • 109
  • 1
  • 2
9

Here is an example of how you do it with expect tool:

sub copyover {
    $scp = Expect->spawn("/usr/bin/scp ${srcpath}/$file $who:${destpath}/$file");
    $scp->expect(30,"ssword: ") || die "Never got password prompt from $dest:$!\n";
    print $scp 'password' . "\n";
    $scp->expect(30,"-re",'$\s') || die "Never got prompt from parent system:$!\n";
    $scp->soft_close();
    return;
}
glenn jackman
  • 238,783
  • 38
  • 220
  • 352
Espo
  • 41,399
  • 21
  • 132
  • 159
7

Nobody mentioned it, but Putty scp (pscp) has a -pw option for password.

Documentation can be found here: https://the.earth.li/~sgtatham/putty/0.67/htmldoc/Chapter5.html#pscp

SDsolar
  • 2,485
  • 3
  • 22
  • 32
galushka
  • 87
  • 1
  • 1
4

Once you set up ssh-keygen as explained above, you can do

scp -i ~/.ssh/id_rsa /local/path/to/file remote@ip.com:/path/in/remote/server/

If you want to lessen typing each time, you can modify your .bash_profile file and put

alias remote_scp='scp -i ~/.ssh/id_rsa /local/path/to/file remote@ip.com:/path/in/remote/server/

Then from your terminal do source ~/.bash_profile. Afterwards if you type remote_scp in your terminal it should run the scp command without password.

hi15
  • 2,113
  • 6
  • 28
  • 51
4

Here's a poor man's Linux/Python/Expect-like example based on this blog post: Upgrading simple shells to fully interactive TTYs. I needed this for old machines where I can't install Expect or add modules to Python.

Code:

(
    echo 'scp jmudd@mysite.com:./install.sh .'
    sleep 5
    echo 'scp-passwd'
    sleep 5
    echo 'exit'
) |

python -c 'import pty; pty.spawn("/usr/bin/bash")'

Output:

scp jmudd@mysite.com:install.sh .
bash-4.2$ scp jmudd@mysite.com:install.sh .
Password: 
install.sh                                 100%   15KB 236.2KB/s   00:00    
bash-4.2$ exit
exit
JohnMudd
  • 13,607
  • 2
  • 26
  • 24
4
  1. Make sure password authentication is enabled on the target server. If it runs Ubuntu, then open /etc/ssh/sshd_config on the server, find lines PasswordAuthentication=no and comment all them out (put # at the start of the line), save the file and run sudo systemctl restart ssh to apply the configuration. If there is no such line then you're done.
  2. Add -o PreferredAuthentications="password" to your scp command, e.g.:
    scp -o PreferredAuthentications="password" /path/to/file user@server:/destination/directory
    
Finesse
  • 9,793
  • 7
  • 62
  • 92
  • How do you indicate the actual password though? – Osmar Nov 20 '20 at 04:09
  • 1
    @Osmar You'll be prompted for password when you run the command – Finesse Nov 21 '20 at 08:21
  • 1
    What is the point? The question was ```How to pass password to scp?``` that means (I think) I don't want to type it. – Magno C Jan 10 '23 at 17:55
  • @MagnoC, the point was to switch `scp` to a password-based authentication – Finesse Jan 11 '23 at 12:40
  • 1
    @Finesse ok but the O.P. needs to not type password. I think ```scp``` is already password-based as it always ask for it in default installation. He (as me) needs to do some automated process (an ETL maybe) that needs to call ```scp``` without user interactivity. That's my interpretation of this question. What actually solved my problem was ```/usr/bin/sshpass -p "$6" scp -o 'StrictHostKeyChecking no' -r $7@$5:$8 $9``` inside a shell script that is called from inside a Java program responsible to ask the password from a WEB browser. – Magno C Jan 11 '23 at 12:57
0
  1. make sure you have "expect" tool before, if not, do it

    # apt-get install expect

  2. create the a script file with following content. (# vi /root/scriptfile)

    spawn scp /path_from/file_name user_name_here@to_host_name:/path_to

    expect "password:"

    send put_password_here\n;

    interact

  3. execute the script file with "expect" tool

    # expect /root/scriptfile

Kevin Chui
  • 147
  • 1
  • 7
0

copy files from one server to other server ( on scripts)

Install putty on ubuntu or other Linux machines. putty comes with pscp. we can copy files with pscp.

apt-get update
apt-get install putty 
echo n |  pscp -pw "Password@1234" -r user_name@source_server_IP:/copy_file_path/files /path_to_copy/files

For more options see pscp help.

Robert
  • 7,394
  • 40
  • 45
  • 64
0

Working fine with powershell and Posh-SSH. Powershell core should be supported

Import-Module "C:\tmp\Posh-SSH\3.0.8\Posh-SSH.psd1" # https://github.com/darkoperator/Posh-SSH/releases

# Connect with pubkey authentication, providing the Passphrase non-interactive, and accepting any remote pubkey
$sftpSession = New-SFTPSession -ComputerName example.com -Credential $keyFilePassphrase -KeyFile "C:\Path\To\private_key" -AcceptKey

# Write file to remote
Set-SFTPItem -SessionId $sftpSession.SessionID -Path C:\tmp\test.txt -Destination "/home/user/"

You could also use expect:

#!/usr/bin/expect

spawn scp user@host:/source user@host2:/target
expect "password"
send -- "$PASSWORD\n"
interact

Install expect and run the script

sudo apt install expect -y
chmod +x /usr/local/bin/update-file.exp
/usr/local/bin/update-file.exp
dahe
  • 806
  • 8
  • 13
0

Since not using key based auth isn't in the title, the following steps will help users who can switch to key based auth. It skips passwords for scp and ssh.

Copy your ssh public key to the server (careful about not overwriting authorized keys)

scp ~/.ssh/id_rsa.pub user@remoteIP:~/.ssh/authorized_keys

Change the permissions:

chmod 600 authorized_keys

Follow a guide like this for more details: https://idratherbewriting.com/jekylldoctheme-separate-outputs/mydoc/mydoc_no_password_prompts_scp.html

randompast
  • 697
  • 7
  • 12
-1

In case if you observe a strict host key check error then use -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null options.

The complete example is as follows sshpass -p "password" scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@domain-name.com:/tmp/from/psoutput /tmp/to/psoutput

Sachin Rastogi
  • 409
  • 5
  • 8
-1

You can use below steps. This works for me!

Step1- create a normal file suppose "fileWithScpPassword" which contains the ssh password for the destination server.

Step2- use sshpaas -f followed by password file name and then normal scp command.

sshpass -f "fileWithScpPassword" scp /filePathToUpload user@ip:/destinationPath/

-1

One easy way I do this:

Use the same scp cmd as you use with ssh keys i.e

scp -C -i <path_to opens sshkey> <'local file_path'> user@<ip_address_VM>: <'remote file_path’>

for transferring file from local to remote

but instead of providing the correct <path_to_opensshkey>, use some garbage path. Due to wrong key path you will be asked for password instead and you can simply pass the password now to get the work done!

  • Jeez.... I can't believe. Why one don't simply call scp and type the password as any normal person? The O.P. don't want to type the password. – Magno C Jan 10 '23 at 17:58
  • @MagnoC your typed password remains in the shell history – Rakesh Raushan Jan 11 '23 at 09:25
  • Despite this ... the O.P. don't want to type the password. He wants to pass it using some automated process. So your ```you will be asked for password instead``` is not useful here. – Magno C Jan 11 '23 at 11:27
-2

An alternative would be add the public half of the user's key to the authorized-keys file on the target system. On the system you are initiating the transfer from, you can run an ssh-agent daemon and add the private half of the key to the agent. The batch job can then be configured to use the agent to get the private key, rather than prompting for the key's password.

This should be do-able on either a UNIX/Linux system or on Windows platform using pageant and pscp.

rjray
  • 5,525
  • 4
  • 31
  • 37
-6

All the solutions mentioned above can work only if you the app installed or you should have the admin rights to install except or sshpass.

I found this very useful link to simply start the scp in Background.

$ nohup scp file_to_copy user@server:/path/to/copy/the/file > nohup.out 2>&1

https://charmyin.github.io/scp/2014/10/07/run-scp-in-background/

Yash
  • 13
  • 3
-10

I found this really helpful answer here.

rsync -r -v --progress -e ssh user@remote-system:/address/to/remote/file /home/user/

Not only you can pass there the password, but also it will show the progress bar when copying. Really awesome.

Community
  • 1
  • 1
valk
  • 9,363
  • 12
  • 59
  • 79