Bash
使用 EOF 訪問腳本中 sudo 子句中的變數
問題:
我需要在這裡有一個名為 $user 的變數:
chown $user:$user "$HOME"/.bashrc
但它無法從
sudo
and外部訪問它EOF
:for user in "$@" do if [ "$user" = root ] then continue fi sudo -i -u "$user" bash <<'EOF' sleep 5 cp -f $CURRENTDIR/.bashrc "$HOME"/.bashrc chown $user:$user "$HOME"/.bashrc sleep 5 chmod 644 "$HOME"/.bashrc sleep 5 wget https://raw.github.com/trapd00r/LS_COLORS/master/LS_COLORS -O "$HOME"/.dircolors sleep 5 echo 'eval $(dircolors -b $HOME/.dircolors)' >> "$HOME"/.bashrc . "$HOME"/.bashrc EOF done
問題:
如何在我的腳本中訪問 $user?
這是完整的腳本:
#!/bin/bash -x SCRIPTNAME=`basename "$0"` if [ "$#" -eq 0 ] then echo "No arguments supplied" echo "Usage: $SCRIPTNAME user1name user2name\(optional\) user3name\(optional\)" sleep 10 exit 27 fi sleep 5 echo "Setting up server.........." sleep 10 DIRBASHRCROOT="$HOME"/.bashrcroot DIRBASHRC="$HOME"/.bashrc #CURRENTDIR="./" BASHRC=.bashrc NANORC=.nanorc BASHRCROOT=.bashrcroot ROOT=root USER1="$1" USER2="$2" USER3="$3" USER_PROGRAMMER="" SOURCE=sources.list var=0 for i in "$@" do if [ "$i" = root ] then break elif [ "$i" != root ] then var=`expr $var + 1` if [ $var -eq 3 ] then USER_PROGRAMMER=root fi fi done if [ $USER_PROGRAMMER != "" ] then echo "$USER_PROGRAMMER is set and ready!" fi sleep 5 echo "Please select/provide the port-number for ssh in iptables:" read port PORT=$port ################# Make my variable global for all ########################3↓ echo "export CURRENTDIR=\"/tmp/svaka\"" >> /root/.bashrc touch /etc/profile.d/bashProgrammer.sh echo "export CURRENTDIR=\"/tmp/svaka\"" >> /etc/profile.d/bashProgrammer.sh . /root/.bashrc . /etc/profile . /etc/profile.d/bashProgrammer.sh ################ Users and access settings ##################### checkIfUser() { for name in "$@" do if id -u "$name" #>/dev/null 2>&1 then echo "User: $name exists....setting up now\!" sleep 5 else echo "User: "$name" does not exists....creating now\!" useradd -m -s /bin/bash "$name" #>/dev/null 2>&1 sleep 5 fi done } checkIfUser $1 $2 $3 ################33 user passwords userPass() { for i in "$@" do if [ "$i" = root ] then continue fi if [[ $(passwd --status "$i" | awk '{print $2}') = NP ]] then echo "$i doesn't have a password." echo "Changing password for $i:" echo $i:$i"YOURSTRONGPASSWORDHERE12345Áá" | chpasswd if [ "$?" = 0 ] then echo "Password for user $i changed successfully" sleep 5 fi fi done } userPass $1 $2 $3 ################################################ setting up iptables ####################3 cat << EOT >> /etc/iptables.test.rules *filter IPTABLES CODE HERE COMMIT EOT sleep 5 iptables-restore < /etc/iptables.test.rules sleep 5 iptables-save > /etc/iptables.up.rules sleep 3 printf "#!/bin/bash\n/sbin/iptables-restore < /etc/iptables.up.rules" > /etc/network/if-pre-up.d/iptables chmod +x /etc/network/if-pre-up.d/iptables sleep 6 ###################################################33 sshd_config cp -f "$CURRENTDIR/sshd_config" /etc/ssh/sshd_config sed -i "s/Port 34504/Port $PORT/g" /etc/ssh/sshd_config chmod 644 /etc/ssh/sshd_config /etc/init.d/ssh restart #################################################3333 Remove or comment out DVD/cd line from sources.list sed -i '/deb cdrom:\[Debian GNU\/Linux/s/^/#/' /etc/apt/sources.list ####################################################33 update system apt update && apt upgrade -y ##########################################3 Disable login www ######### passwd -l www-data ############################################################### ############################# check if programs installed and/or install if [ ! -x /usr/bin/git ] || [ ! -x /usr/bin/wget ] || [ ! -x /usr/bin/curl ] || [ ! -x /usr/bin/gcc ] || [ ! -x /usr/bin/make ] then echo "Some tools with which to work with data not found installing now......................" apt install -y git wget curl gcc make fi #####################################################3 update sources.list cp -f $CURRENTDIR/$SOURCE /etc/apt/sources.list chmod 644 /etc/apt/sources.list wget http://www.deb-multimedia.org/pool/main/d/deb-multimedia-keyring/deb-multimedia-keyring_2016.8.1_all.deb dpkg -i deb-multimedia-keyring_2016.8.1_all.deb wget -q https://www.virtualbox.org/download/oracle_vbox_2016.asc -O- | sudo apt-key add - apt update && apt upgrade -y apt install -y vlc vlc-data browser-plugin-vlc mplayer youtube-dl libdvdcss2 libdvdnav4 libdvdread4 smplayer mencoder sleep 5 apt update && apt upgrade -y sleep 5 #################################### firmware apt install -y firmware-linux-nonfree firmware-linux sleep 5 ################ NANO SYNTAX-HIGHLIGHTING #####################3 if [ ! -d "$CURRENTDIR/nanorc" ] then if [ "$UID" != 0 ] then sudo -u "$ROOT" bash <<'EOF' sleep 5 git clone https://github.com/nanorc/nanorc.git sleep 5 cd nanorc make install-global sleep 5 cp -f "$CURRENTDIR/.nanorc" /etc/nanorc chown root:root /etc/nanorc chmod 644 /etc/nanorc if [ "$?" = 0 ] then echo "Implementing a custom nanorc file succeeded\!" else echo "Nano setup DID NOT SUCCEED\!" fi EOF else echo "Doing user: $USER....please, wait\!" git clone https://github.com/nanorc/nanorc.git sleep 5 cd nanorc sleep 5 make install-global sleep 5 cp -f "$CURRENTDIR/$NANORC" /etc/nanorc chown root:root /etc/nanorc chmod 644 /etc/nanorc if [ "$?" = 0 ] then echo "Implementing a custom nanorc file succeeded\!" else echo "Nano setup DID NOT SUCCEED\!" fi fi fi echo "Finished setting up nano\!" ################ LS_COLORS SETTINGS ############################# if [ "$UID" != 0 ] then echo "This program should be run as root, exiting\! now....." exit 1 # sudo -i -u "$ROOT" bash <<'EOF' # BASHRCROOT=.bashrcroot # cp "$CURRENTDIR/$BASHRCROOT" "$HOME"/.bashrc # wget https://raw.github.com/trapd00r/LS_COLORS/master/LS_COLORS -O "$HOME"/.dircolors # echo 'eval $(dircolors -b $HOME/.dircolors)' >> "$HOME"/.bashrc # . "$HOME"/.bashrc #EOF else cp -f "$CURRENTDIR/$BASHRCROOT" "$HOME"/.bashrc chown root:root "$HOME"/.bashrc chmod 644 "$HOME"/.bashrc sleep 5 wget https://raw.github.com/trapd00r/LS_COLORS/master/LS_COLORS -O "$HOME"/.dircolors sleep 5 echo 'eval $(dircolors -b $HOME/.dircolors)' >> "$HOME"/.bashrc sleep 5 . "$HOME"/.bashrc fi for user in "$@" do if [ "$user" = root ] then continue fi sudo -i -u "$user" bash <<'EOF' sleep 5 cp -f $CURRENTDIR/.bashrc "$HOME"/.bashrc chown $user:$user "$HOME"/.bashrc sleep 5 chmod 644 "$HOME"/.bashrc sleep 5 wget https://raw.github.com/trapd00r/LS_COLORS/master/LS_COLORS -O "$HOME"/.dircolors sleep 5 echo 'eval $(dircolors -b $HOME/.dircolors)' >> "$HOME"/.bashrc . "$HOME"/.bashrc EOF done echo "Finished setting up your system\!" echo rm -rf /tmp/svaka
作為一般解決方案,您可以
VAR=value
在要執行的命令行中使用可能的多對將其他環境變數傳遞給 sudo 命令。在這種特殊情況下,要傳遞
$user
變數,您可以使用:sudo -i -u "$user" user="$user" bash <<'EOF' ... chown $user:$user "$HOME"/.bashrc ... EOF
(您也可以傳遞變數,例如
$CURRENTDIR
使用此方法而不是通過 rcfiles 推送它,因為您似乎是從腳本的其餘部分這樣做的。)您需要一些特殊權限
sudo
才能設置其他環境變數。就像sudo 手冊頁的這一部分一樣:如果在 sudoers 中設置了 setenv 選項,要執行的命令
SETENV
設置了標籤或匹配的命令是ALL
,使用者可能會設置過度禁止的變數。有關詳細資訊,請參閱sudoers(5)。
您還可以使用
sudo -Es
和保留來自呼叫使用者的環境。例如:$ a=hi sudo -Es env | grep -i ^a= a=hi
每
man sudo
:-E, --preserve-env Indicates to the security policy that the user wishes to preserve their existing environment variables. The security policy may return an error if the user does not have permission to preserve the environment. -s, --shell Run the shell specified by the SHELL environment variable if it is set or the shell specified by the invoking user's password database entry. If a command is specified, it is passed to the shell for execution via the shell's -c option. If no command is specified, an interactive shell is executed.