How do I install my SSH public key ~/.ssh/ onto a remote Linux and UNIX server automatically from Linux workstation or Apple OS X laptop without using scp and/or copy & paste method?

You need to use the ssh-copy-id script that uses ssh to log into a remote machine using a login password. The syntax is as follows:


Tutorial details
Difficulty level Easy
Root privileges No
Requirements None
Est. reading time 2m


ssh-copy-id -i ~/.ssh/


ssh-copy-id -i ~/.ssh/

OR use specific port on remote host such as tcp port # 4242:

ssh-copy-id -i /path/key/ " -p 4242"

Install ssh-copy-id on a OS X Unix systems

Type the following command:

brew install ssh-copy-id

Sample outputs:

Fig.01: Install ssh-copy-id on a OS X Unix systems

Step # 1: Create the Keys

Type the following ssh-keygen command to generates, manages and converts authentication keys for your workstation / laptop:
Make sure you protect keys with the passphrase.

Step # 2: Install the public key

Install key in a remote server called, enter:
ssh-copy-id -i ~/.ssh/

Note: If ssh-copy-id command not found on your system, try the following commands to append/install the public key on remote host:
ssh "umask 077; mkdir .ssh"
cat $HOME/.ssh/ | ssh "cat >> .ssh/authorized_keys"

Step #3: Use keychain for password less login

OpenSSH offers RSA and DSA authentication to remote systems without supplying a password. keychain is a special bash script designed to make key-based authentication incredibly convenient and flexible (see how to install keychain script on unix). Add following lines to your ~/.bash_profile or shell login file:

/usr/bin/keychain $HOME/.ssh/id_rsa
source $HOME/.keychain/$HOSTNAME-sh

Save and close the file.


🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 9 comments so far... add one

CategoryList of Unix and Linux commands
Disk space analyzersdf ncdu pydf
File Managementcat cp mkdir tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
9 comments… add one
  • Nei McLeish May 7, 2010 @ 12:47

    Hi all.
    Unfortunately, ssh-copy-id does not exist under OS X, so here is a script that does the same job.
    When I can remember where I got it from, I will add the relevant credit to its author.

    Best regards,


    if [ ! -f ~/.ssh/ ];then
        echo "private key not found at $KEY"
        echo "* please create it with "ssh-keygen -t dsa" *"
        echo "* to login to the remote host without a password, don't give the key you create with ssh-keygen a password! *"
    if [ -z $1 ];then
        echo "Please specify user@host.tld as the first switch to this script"
    echo "Putting your key on $1... "
    KEYCODE=`cat $KEY`
    ssh -q $1 "mkdir ~/.ssh 2>/dev/null; chmod 700 ~/.ssh; echo "$KEYCODE" >> ~/.ssh/authorized_keys; chmod 644 ~/.ssh/authorized_keys"
    echo "done!"
  • Anonymous May 7, 2010 @ 13:13

    Here is what I’ve installed in my Debian Linux box:

    # Shell script to install your public key on a remote machine
    # Takes the remote machine name as an argument.
    # Obviously, the remote machine must accept password authentication,
    # or one of the other keys in your ssh-agent, for this to work.
    if [ "-i" = "$1" ]; then
      # check if we have 2 parameters left, if so the first is the new ID file
      if [ -n "$2" ]; then
        if expr "$1" : ".*\.pub" > /dev/null ; then
        shift         # and this should leave $1 as the target name
      if [ x$SSH_AUTH_SOCK != x ] && ssh-add -L >/dev/null 2>&1; then
        GET_ID="$GET_ID ssh-add -L"
    if [ -z "`eval $GET_ID`" ] && [ -r "${ID_FILE}" ] ; then
      GET_ID="cat ${ID_FILE}"
    if [ -z "`eval $GET_ID`" ]; then
      echo "$0: ERROR: No identities found" >&2
      exit 1
    if [ "$#" -lt 1 ] || [ "$1" = "-h" ] || [ "$1" = "--help" ]; then
      echo "Usage: $0 [-i [identity_file]] [user@]machine" >&2
      exit 1
    { eval "$GET_ID" ; } | ssh ${1%:} "umask 077; test -d .ssh || mkdir .ssh ; cat >> .ssh/authorized_keys" || exit 1
    cat <<EOF
    Now try logging into the machine, with "ssh '${1%:}'", and check in:
    to make sure we haven't added extra keys that you weren't expecting.
  • Juan Giordana May 9, 2010 @ 21:03

    Hi Neil,

    Thanks for the tip. I’ve been playing with ssh and keygen yesterday and missed this useful command.

    Here are my two cents:

    1 – Since there is no way to specify a port from the command line to this command one can add the following to their ~/.ssh/config

    Host remote.server.tld
    Port 2222

    And remove the line afterwards (see 3).

    2 – Change the permissions of ~/.ssh/authorized_key to 600

    3 – Hash the known_hosts file: This replaces all hostnames and addresses with hashed representations
    ssh-keygen -H -f ~/.ssh/known_hosts


  • Juan Francisco Giordana May 9, 2010 @ 21:07

    Host remote.server.tld
    Port 2222

  • Cokegen May 18, 2011 @ 23:03

    To do this on a non standard port the best is to use this:

    ssh-copy-id -i /path/ “user@host -p 2222”


    • Jordi Jul 8, 2011 @ 8:36

      xxx@server:~/.ssh# ssh-copy-id -i ~/.ssh/ “xxx@server -p 2222″
      ssh: connect to host server port 22: Connection refused

      Not works

      • Jordi Jul 8, 2011 @ 9:22

        Sorry, I repeated the command again, and worked well! Thanks!

        ssh-copy-id -i ~/.ssh/ “user@server -p 2222”

        Now try logging into the machine, with “ssh ‘user@server -p 2222′”, and check in:


        to make sure we haven’t added extra keys that you weren’t expecting.

  • NoSiL May 22, 2014 @ 17:37

    I found a bug:
    cat $HOME/.ssh/ | ssh cat >> .ssh/authorized_keys
    should be
    cat $HOME/.ssh/ | ssh ‘cat >> .ssh/authorized_keys’
    It won’t work without quotes as intended.

    Also, the “ssh-keygen” followed by the piped “cat” command is sufficient to get password-less access enabled. Do both on your machine, “” in the example is the remote computer you want to access.

  • h.amiri Jan 5, 2016 @ 17:44
    #!/usr/bin/env bash
    cat </dev/null`" ]&& echo -e "\033[5;1;31m PING 		$HOST is failed \033[0m" 
    #[ ! "`ssh $U@$HOST 2>/dev/null`" ]&& echo -e "\033[5;1;31m SSH to 	$HOST is failed \033[0m" && exit
      echo "Creating $U/.ssh On Host $HOST"
      ssh -p $P $U@$HOST "mkdir ~/.ssh"  
      scp -P $P  ~/.ssh/ $U@$HOST:~/.ssh/authorized_keys.tmp && echo "DONE"
      echo "Enter your ip and user address to upload key"
      read SERVER U_
      ssh -p $P $U_@$HOST wget -q $SERVER/dl/ -O .ssh/authorized_keys.tmp
    if [ ! -f ~/.ssh/ ];then 
       echo " not found !"
       ssh-keygen -t rsa
       read -sp "Do you want to generate new keys (y/n) ?" resp
       if [ $resp = "y" ];then
          echo -e "\033[1;33m GENERATING SSH KEY \033[0m"
          ssh-keygen -t rsa
          echo -e "\033[1;32m Using old keys\033[0m"
    echo -e "\033[1;33m ...MAKING KEYS ON HOST $HOST for USER =$U 		\033[0m"
    scp -P $P ~/.ssh/ $U@$HOST:~/.ssh/authorized_keys.tmp && echo "DONE" || mkd
    echo -e "\033[1;33m -------------------------------\033[0m"
    ssh -p $P $U@$HOST "cat ~/.ssh/authorized_keys.tmp >> ~/.ssh/authorized_keys"
    echo -e "\033[1;32m CHECKING THE PROCESS \033[0m"
    ssh -p $P $U@$HOST

    I wrote it in 2009 and i was noob ;)

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum