简体   繁体   中英

Why do I keep getting “cp: cannot stat '': No such file or directory” or “cp: missing opereand” in my bash script

I'm writing a script to setup debian installs and this error is frustrating me:

PROBLEM:

cp "$BASHRC" "$HOME"/.bashrc

gives:

+ sudo -u billy bash

cp: cannot stat '': No such file or directory

or

cp: missing opereand

Here is the script:

These files are in the current directory where the script is...

 17 BASHRC=.bashrc
 18 NANORC=.nanorc
 19 BASHRCROOT=.bashrcroot 

#!/bin/bash -x
  2
  3 SCRIPTNAME=`basename "$0"`
  4
  5 if [ "$#" -eq 0 ]
  6 then
  7     echo "No arguments supplied"
  8     echo "Usage: $SCRIPTNAME user1name user2name\(optional\) user3name\(optional\)"
  9 fi
 10
 11 echo "Here starts the party, "
 12 echo "This program should be run as root, please wait"
 13 echo "Setting up server.........."
 14
 15 DIRBASHRCROOT="$HOME"/.bashrcroot
 16 DIRBASHRC="$HOME"/.bashrc
 17 BASHRC=.bashrc
 18 NANORC=.nanorc
 19 BASHRCROOT=.bashrcroot
 20 ROOT=root
 21 USER1="$1"
 22 USER2="$2"
 23 USER3="$3"
 24
 25 ################ Users and access settings #####################
 26 #echo username1 ALL=(username2) NOPASSWD: /bin/bash /path/to/svn >> /etc/sudoers
 27 #echo `users` | grep "$1" && echo User $1 exists
 28 #sudo -u username2 -H sh -c "cd /home/$USERNAME/$PROJECT; svn update"
 29 #useradd -m -s /bin/bash "$different_user"
 30 #id -u $USER1
 31 checkIfUser()
 32 {
 33     for name in "$@"
 34     do
 35         if id -u "$name" #>/dev/null 2>&1
 36         then
 37             echo 'User: "$name" exists....setting up now\!'
 38         else
 39             echo 'User: "$name" does not exists....creating now\!'
 40             useradd -m -s /bin/bash "$name" #>/dev/null 2>&1
 41         fi
 42     done
 43 }
 44 checkIfUser $1 $2 $3
 45 ################ NANO SYNTAX-HIGHLIGHTING #####################3
 46 sleep 3
 47
 48
 49
 50 
 51 
 52 if [ "$UID" != 0 ]
 53 then
 54    sudo -u "$ROOT" bash <<'EOF'
 55    sleep 5
 56    git clone https://github.com/nanorc/nanorc.git
 57    sleep 5
 58    cd nanorc
 59    make install-global
 60    sleep 5
 61    cp "$NANORC" /etc/nanorc
 62
 63    if [ "$?" = 0 ]
 64    then
 65        echo "Implementing a custom nanorc file succeeded\!"
 66    fi
 67EOF
 68 else
 69     git clone https://github.com/nanorc/nanorc.git
 70     sleep 5
 71     cd nanorc
 72     sleep 5
 73     make install-global
 74     sleep 5
 75     cp "$NANORC" /etc/nanorc
 76
 77     if [ "$?" = 0 ]
 78     then
 79         echo "Implementing a custom nanorc file succeeded\!"
 80     fi
 81 fi
 82
 83 echo "Finished setting up nano\!"
 84 ################ LS_COLORS SETTINGS #############################

 86 if [ "$UID" != 0 ]
 87 then
 88     sudo -u "$ROOT" bash <<'EOF'
 89     cp "$BASHRCROOT" "$HOME"/.bashrc
 90     wget https://raw.github.com/trapd00r/LS_COLORS/master/LS_COLORS -O "$HOME"/.dircolors
 91     echo 'eval $(dircolors -b $HOME/.dircolors)' >> "$HOME"/.bashrc
 92     . "$HOME"/.bashrc
 93     echo "Here is LS_COLORS in action: "
 94     ls -l "$HOME"/
 95 EOF
 96 else
 97     cp "$BASHRCROOT" $(eval echo "$HOME"/.bashrc)
 98     sleep 5
 99     wget https://raw.github.com/trapd00r/LS_COLORS/master/LS_COLORS -O "$HOME"/.dircolors
100     sleep 5
101     echo 'eval $(dircolors -b $HOME/.dircolors)' >> "$HOME"/.bashrc
102     sleep 5
103     . "$HOME"/.bashrc
104     echo "Here is LS_COLORS in action: "
105     sleep 5
106     ls -l "$HOME"/
107 fi
108 if [ ! -z "$USER1" ]
109 then
110     sudo -u "$USER1" bash <<'EOF'
111     sleep 5


THESE GUY'S ARE THE CULPRIT↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
    112     cp "$BASHRC" "$HOME"/.bashrc
HERE IS THE PROBLEM ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
113     sleep 5
114     wget https://raw.github.com/trapd00r/LS_COLORS/master/LS_COLORS -O "$HOME"/.dircolors
  sleep 5
116     echo 'eval $(dircolors -b $HOME/.dircolors)' >> "$HOME"/.bashrc
117     . "$HOME"/.bashrc
118     sleep 5
119     echo "Here is LS_COLORS in action: "
120     ls -l "$HOME"/
121 EOF
122 fi
123
124 if [ ! -z "$USER2" ]
125 then
126     sudo -u "$USER2" bash <<'EOF'
127     cp "$BASHRC" "$HOME"/.bashrc
128     wget https://raw.github.com/trapd00r/LS_COLORS/master/LS_COLORS -O "$HOME"/.dircolors
129     echo 'eval $(dircolors -b $HOME/.dircolors)' >> "$HOME"/.bashrc
130     . "$HOME"/.bashrc
131     echo "Here is LS_COLORS in action: "
132     ls -l "$HOME"/
133 EOF
134 fi
135
136 if [ ! -z "$USER3" ]
137 then
138     sudo -u "$USER3" bash <<'EOF'
139     sleep 5
140     cp "$BASHRC" "$HOME"/.bashrc
141     sleep 5
142     wget https://raw.github.com/trapd00r/LS_COLORS/master/LS_COLORS -O "$HOME"/.dircolors
    sleep 5
142     wget https://raw.github.com/trapd00r/LS_COLORS/master/LS_COLORS -O "$HOME"/.dircolors
143     sleep 5
144     echo 'eval $(dircolors -b $HOME/.dircolors)' >> "$HOME"/.bashrc
145     sleep 5
146     . "$HOME"/.bashrc
147     echo "Here is LS_COLORS in action: "
148     ls -l "$HOME"/
149 EOF
150 fi
151 echo "Finished setting up LS_COLORS on your files and directories\!"

QUESTION:

What seems to be the problem here and what is the best practice and solution?

You are starting another bash via sudo. BASHRC is a local variable, which is not visible to child processes.

Another issue will arise because of sudo: if /etc/sudoers contains option Defaults env_reset , then sudo will discard almost all env variables (except PATH).

If you change <<'EOF' to << EOF, you can control which variable will be expanded before sudo and which after:

#!/bin/sh
EARLY_EXPANSION=foo
export LATER_EXPANSION=bar

bash <<EOF
  echo "$EARLY_EXPANSION \$LATER_EXPANSION"
  sleep 5
  echo $(date) \$(date)
EOF

Here is the answer to this problem given in a comment by sir @steeldriver in a sister site.....:

Bearing in mind your previous question sudo -u user bash works but $HOME is not changing accordingly I assume you want $HOME to expand to $USER1's home directory - to achieve that, you probably need to invoke a login shell by adding -i or --login to your sudo invocation

So now it looks like this......:

     if [ ! -z "$USER1" ]
108  then
109     sudo -i -u "$USER1" bash <<'EOF'
110     sleep 5
111     cp -f .bashrc "$HOME"/.bashrc
112     sleep 5
113     wget https://raw.github.com/trapd00r/LS_COLORS/master/LS_COLORS -O "$HOME"/.dircolors
114     sleep 5
115     echo 'eval $(dircolors -b $HOME/.dircolors)' >> "$HOME"/.bashrc
116     . "$HOME"/.bashrc
117     sleep 5
118     echo "Here is LS_COLORS in action: "
119     ls -l "$HOME"
120 EOF
121 fi

But there is a new problem:

cp: '.bashrc' and '/home/billy/.bashrc' are the same file

The reason for this error is that the login shell has the /home/user1 directory as it's current directory and not the directory from where the script is running where this file .bashrc is hiding.

I solved it by hardcoding the directory where needed but if someone has an way to use a variable that would be much apprieated, thank's

EDIT:

I solved the last pieze of the puzzle by doing this:

 ################# Make my variable global for all ########################3↓
 27 echo "export CURRENTDIR=\"/tmp/svaka\"" >> /root/.bashrc
 28 echo "export CURRENTDIR=\"/tmp/svaka\"" >> /etc/profile
 29 . /etc/profile

Making my variable CURRENTDIR global for all bash login-shell's...

On Amazon Linux /etc/profile states:

 It's NOT a good idea to change this file unless you know what you
 are doing. It's much better to create a custom.sh shell script in
 /etc/profile.d/ to make custom changes to your environment, as this
 will prevent the need for merging in future updates.

With that in mind, I created a bash_profile.sh in /etc/profile.d/ .

Don't forget that a logout/in is probably required to pick up the changes.

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