具有引用参数的system-user,smb-user和netatalk-user的Bash脚本

时间:2017-02-26 20:41:05

标签: linux bash shell parameter-passing

我写了一个小脚本,在Debian服务器上一步创建系统用户帐户,smb帐户和afp帐户(Netatalk)。除了 useradd 命令的 -c 参数之外,大多数工作都很顺利。引用它。我认为这是主要问题。我做了一些研究,我发现了如何在args中保留引号,但我的所有尝试都是在错误代码2中导致的,并在 useradd 命令的使用提示中结束。

我设法在shell上调用了这一行

useradd -m -d /home/username -p abcDEFghiJKLm -c "Full Name" -g users username

我得到的是错误代码2和 useradd 命令的用法消息。

Usage: useradd [options] LOGIN
       useradd -D
       <...>

这是我创建系统用户的功能。

AddSystemUser() {
  echo "Adding system user"
  myArgs="-p $cryptPass"
  if [ "$fullName" != "" ]
  then
    myArgs="$myArgs -c \"$fullName\""
  fi
  if [ "$userGroup" != "" ]
  then
    myArgs="$myArgs -g $userGroup"
  fi
  if [ "$userGroups" != "" ]
  then
    myArgs="$myArgs -G $userGroups"
  fi

  doUserAdd="useradd -m -d /home/$userName $myArgs $userName"
  #echo $doUserAdd
  $doUserAdd
  myResultCode=$?
  if [ $myResultCode -ne 0 ]
  then
    echo "Adding system user failed with error code $myResultCode"
    exit $(($myResultCode + 100))
  fi
}

如您所见,我在这个地方添加了双引号,因此我可以在shell上使用语法 -c Full \ Name

我也尝试过这种方法,但没有在脚本中添加引号,而是在shell上键入它们,例如 -c&#34;&#39;全名&#34;&#39; 相同的结果: useradd 的使用消息。

有人可以帮帮我吗?我不知道自己做错了什么。

3 个答案:

答案 0 :(得分:1)

行情不嵌套;放在myArgs中的转义引号被视为文字字符,而不是用于阻止分词的语法引号。这是为数组引入的。

AddSystemUser() {
  echo "Adding system user"
  myArgs=( -p "$cryptPass" )
  if [ "$fullName" != "" ]; then
    myArgs+=( -c "$fullName" )
  fi
  if [ "$userGroup" != "" ]; then
    myArgs+=(-g "$userGroup")
  fi
  if [ "$userGroups" != "" ]; then
    myArgs+=( -G "$userGroups" )
  fi

  useradd -m -d "/home/$userName" "${myArgs[@]}" "$userName"
  myResultCode=$?
  if [ $myResultCode -ne 0 ]
  then
    echo "Adding system user failed with error code $myResultCode"
    exit $(($myResultCode + 100))
  fi
}

答案 1 :(得分:0)

我认为eval适用于您的情况:

: other code
eval useradd -m -d "/home/$userName" "$myArgs" "$userName"
myResultCode=$?
: the rest of your code

答案 2 :(得分:0)

美好的一天。

两个答案都运作良好。非常感谢你。由于它现在运行得很好,我现在将发布我的整个脚本与此线程中提供的错误修复。

使用此脚本,您可以在Linux上一步添加系统用户,samba用户和afp用户。它在Debian 8上进行了测试。

只有一个缺陷:使用 afp Netatalk ),无法在不重新输入密码的情况下通过shell创建用户。因此,在此脚本中,您必须输入密码四次。

这是脚本:

#!/bin/bash

# With this script one can create, change and delete a user for linux-system, Samba and Netatalk in one step.

fullName=""
userName=""
userGroup=""
userGroups=""
newPass1="X"
newPass2="Y"
cryptPass=""
addnewMode=false
changeMode=false
deleteMode=false

while getopts ':u:n:g:G:acd' OPTION
do
  case "$OPTION" in
    u) userName=$OPTARG;;
    n) fullName=$OPTARG;;
    g) userGroup=$OPTARG;;
    G) userGroups=$OPTARG;;
    a) addnewMode=true;;
    c) changeMode=true;;
    d) deleteMode=true;;
    *) echo "Unknown parameter"
  esac
done

ShowUsage() {
  echo "Usage: $0 -a|c|d -u username [-n full-user-name] [-g main-group] [-G group1,group2,..]"
}

AddNetatalkUser() {
  echo "Adding Netatalk user"
  (echo $newPass1; echo $newPass1 ) | afppasswd -f -a $userName
}

AddSambaUser() {
  echo "Adding Samba user"
  (echo $newPass1; echo $newPass1 ) | smbpasswd -s -a $userName
}

AddSystemUser() {
  echo "Adding system user"

  myArgs=( -p "$cryptPass" )
  if [ "$fullName" != "" ]
  then
    myArgs+=( -c "$fullName" )
  fi
  if [ "$userGroup" != "" ]
  then
    myArgs+=( -g "$userGroup" )
  fi
  if [ "$userGroups" != "" ]
  then
    myArgs+=( -G "$userGroups" )
  fi

  useradd -m -d "/home/$userName" "${myArgs[@]}" "$userName"
  myResultCode=$?
  if [ $myResultCode -ne 0 ]
  then
    echo "Adding system user failed with error code $myResultCode"
    exit $(($myResultCode + 100))
  fi
}

AddUsers() {
  AddSystemUser
  AddSambaUser
  AddNetatalkUser
}

ChangeNetatalkUserPassword() {
  echo "Updating Netatalk user"
  (echo $newPass1; echo $newPass1 ) | afppasswd -n -a $userName
}

ChangeSambaUserPassword() {
  echo "Updating Samba user"
  (echo $newPass1; echo $newPass1 ) | smbpasswd -s -a $userName
}

ChangeSystemUserPassword() {
  echo "Updating system user"
  doChangePass="chpasswd $userName:$newPass1"
  #echo $doChangePass
  $doChangePass
  myResultCode=$?
  if [ $myResultCode -ne 0 ]
  then
    echo "Changing password failed with error code $myResultCode"
    exit $(($myResultCode + 100))
  fi
}

ChangePasswords() {
  ChangeSystemUserPassword
  ChangeSambaUserPassword
  ChangeNetatalkUserPassword
}

CheckForRootPrivileges() {
  if [ $(id -u) -ne 0 ]
  then
    echo "You must have root privileges"
    exit 5
  fi
}

CheckIfNewUserDoesExist() {
  egrep "^$userName" /etc/passwd > /dev/null
  if [ $? -ne 0 ]
  then
    echo "User does not exist"
    exit 4
  fi
}

CheckIfNewUserDoesNotExist() {
  egrep "^$userName" /etc/passwd > /dev/null
  if [ $? -eq 0 ]
  then
    echo "User already exists"
    exit 6
  fi
}

CheckForUserExistance() {
  if [ $addnewMode == true ]
  then
    CheckIfNewUserDoesNotExist
  else
    CheckIfNewUserDoesExist
  fi
}

CheckParams() {
  paramCount=0
  if [ $addnewMode == true ]
  then
    ((paramCount++))
  fi
  if [ $changeMode == true ]
  then
    ((paramCount++))
  fi
  if [ $deleteMode == true ]
  then
    ((paramCount++))
  fi

  if [ "$userName" == "" ]
  then
    ShowUsage
    exit 1
  elif [ $paramCount -eq 0 ]
  then
    ShowUsage
    exit 2
  elif [ $paramCount -gt 1 ]
  then
    ShowUsage
    exit 3
  fi
}

DeleteNetatalkUser() {
  echo "Deleting Netatalk user"
  afppasswd -x $userName
}

DeleteSambaUser() {
  echo "Deleting Samba user"
  smbpasswd -x $userName
}

DeleteSystemUser() {
  echo "Deleting system user"
  doDeleteUser="userdel -r $userName"
  #echo $doDeleteUser
  $doDeleteUser
  myResultCode=$?
  if [ $myResultCode -ne 0 ]
  then
    echo "Deleting user failed with error code $myResultCode"
    exit $(($myResultCode + 100))
  fi
}

DeleteUsers() {
  DeleteNetatalkUser
  DeleteSambaUser
  DeleteSystemUser
}

CheckPassword() {
  if [ $newPass1 != $newPass2 ]
  then
    echo "Password mismatch"
    exit 7
  fi
}

EncryptPassword() {
  cryptPass=$(perl -e 'print crypt($ARGV[0], "password")' $newPass1)
}

GetPassword() {
  read -r -s -p "Password:" newPass1
  echo
  read -r -s -p "Retype password:" newPass2
  echo
}

ProcessPasswordIfNeccessary() {
  if [ $deleteMode == false ]
  then
    GetPassword
    CheckPassword
    EncryptPassword
  fi
}

SyncUsers() {
  if [ $addnewMode == true ]
  then
    AddUsers
  elif [ $changeMode == true ]
  then
    ChangePasswords
  elif [ $deleteMode == true ]
  then
    DeleteUsers
  fi
}

CheckParams
CheckForRootPrivileges
CheckForUserExistance
ProcessPasswordIfNeccessary
SyncUsers

exit 0

我希望这个脚本可以帮助别人。

干杯。