1

以下にリストされているスクリプトを持っていますが、問題を解決できないようです。私が参加している UNIX クラス用の対話型ログイン スクリプトを作成しようとしています。基本的には、に渡すコマンドを構築していuseraddます。コマンドラインに渡されたときに(追加中にsudo)作成したコマンドは期待どおりに機能しますが、スクリプトから実行しようとすると(コマンドラインにコピー/貼り付けするテキストを生成しています)、いくつかのエラーが発生します... この時点で、問題を解決するために次に何を試せばよいか途方に暮れています。

エラー:

useradd -m --user-group jaredm2 #command that is attempting to run...
useradd: invalid option -- ' '
Usage: useradd [options] LOGIN
....rest of useradd error text....

脚本:

#!/bin/bash
#Add a new user

FINALCOMMAND="-m"

#import useradd defaults...
. /etc/default/useradd

#Check if running as root
if [ "$(id -u)" != "0" ]; then
    echo "This script must be ran as root"
    exit 1
fi

#Get the new users Name
#echo -n "Please enter the users First and Last Name and press [ENTER]: "
#read Name

#Get the new users username
echo "The username must be 4-20 characters."
echo -n "Please enter the users requested username and press [ENTER]: "
read USERNAME
while [ $(grep -c "^${USERNAME}:" /etc/passwd) -ge 1 ] || [ ${#USERNAME} -le 3 ] || [ ${#USERNAME} -ge 21 ]
do
    echo " "
    echo "Error: Username is in use or invalid.  Please select a different username."
    echo " "
    echo -n "Please enter the users requested username and press [ENTER]: "
    read USERNAME   
done #USERNAME will be valid from this point

#ASK about the default shell now
echo -n "Enter the new shell if you would like one (currently $SHELL) or leave blank for the default and press [ENTER]: "
read tempSHELL
if [ ${#tempSHELL} -ge 1 ]; then
    SHELL="$tempSHELL"
    FINALCOMMAND="$FINALCOMMAND ""-s $SHELL"
fi

#ASK about a different primary group
echo "Would you like to enter a non-default primary user group? Defaults to creating a new group that matches the username"
echo "Enter a new Primary Group or leave blank for the default and press [ENTER]: "
read newPrimaryGroup

if [ ${#newPrimaryGroup} -eq 0 ]; then
    FINALCOMMAND="$FINALCOMMAND --user-group"
else
    if [ $(grep -c "^${newPrimaryGroup}" /etc/group) -ge 1 ]; then
        FINALCOMMAND="$FINALCOMMAND -g $newPrimaryGroup"
    else
        echo "Invalid group specified reverting to default!"
        FINALCOMMAND="$FINALCOMMAND --user-group"
    fi
fi
useradd -m --user-group jaredm2
#ASK about additional groups
echo "Would you like the new user to be a part of any additional groups?  Leave blank if no additional groups are needed or enter additional groups in the format of GROUP1,GROUP2,... (NO SPACES) and press [ENTER]: "
read extraGroups
#remove spaces if the user entered any
extraGroups="${extraGroups//[[:space:]]}"
FINALEXTRAGROUPS=""
IFS=","
for g in $extraGroups
do
    if [ $(grep -c "^${g}" /etc/group) -ge 1 ]; then
        FINALEXTRAGROUPS="$FINALEXTRAGROUPS,$g"
    else
        echo "$g is invalid user will not be added..."
    fi
done
FINALEXTRAGROUPS=$(echo "$FINALEXTRAGROUPS" | tail -c +2)
if [ ${#FINALEXTRAGROUPS} -ge 1 ]; then
    FINALCOMMAND="$FINALCOMMAND -G $FINALEXTRAGROUPS"
fi

#ASK about the home directory
echo "Would you like to enter a new home directory for the user?  Leave blank to use the default of $HOME/$USERNAME or enter your own and press [ENTER]: "
read NEWHOME

if [ ${#NEWHOME} -ge 1 ]; then
    FINALCOMMAND="$FINALCOMMAND -d $NEWHOME"
fi

#ADD the username to the command
FINALCOMMAND=`echo "$FINALCOMMAND $USERNAME" | sed 's/ *$//g' | sed 's/^ *//g'`
echo "useradd $FINALCOMMAND"
#PASSCOMMAND="sudo passwd $USERNAME"
#ADD THE USER
`useradd $FINALCOMMAND`

`passwd $USERNAME`

`chfn $USERNAME`

更新: 追加のデバッグ コンテンツ

+ '[' 0 -ge 1 ']'
++ sed 's/^ *//g'
++ sed 's/ *$//g'
++ echo '/usr/sbin/useradd -m -U JaredM'
+ FINALCOMMAND='/usr/sbin/useradd -m -U JaredM'
++ '/usr/sbin/useradd -m -U JaredM'
./addnewuser.sh: line 89: /usr/sbin/useradd -m -U JaredM: No such file or directory
4

5 に答える 5

2

`...`この問題は、シェル コマンドを実行するためにマジック クォートを使用して作成したスクリプトが原因で発生します。

これらの引用符は、コマンドの戻り値を変数に格納する場合にのみ使用する必要があります: 以下の命令の例:

FINALCOMMAND=`echo "$FINALCOMMAND $USERNAME" | sed 's/ *$//g' | sed 's/^ *//g'`

それ以外の場合、この見積もりを使用する必要はなく、あなたのようなバグが発生する可能性があります.

スクリプトに入れることができます:

useradd $FINALCOMMAND
passwd $USERNAME
chfn $USERNAME

それ以外の:

`useradd $FINALCOMMAND`
`passwd $USERNAME`
`chfn $USERNAME`
于 2012-10-30T13:40:46.117 に答える
2

配列を使用することで、コマンドラインでの IFS 関連のエラーを防ぐことができ、よりクリーンになります。これはすでにテスト済みです。コードにもいくつかのクリーンアップを行いました。

#!/bin/bash

#Add a new user

FINALCOMMAND=("-m")

#Import useradd defaults...
. /etc/default/useradd

#Check if running as root
if [ "$(id -u)" != "0" ]; then
    echo "This script must be ran as root"
    exit 1
fi

#Get the new users Name
#echo -n "Please enter the users First and Last Name and press [ENTER]: "
#read Name

#Get the new users username
echo "The username must be 4-20 characters."
echo -n "Please enter the users requested username and press [ENTER]: "
read USERNAME
while [ $(grep -c "^${USERNAME}:" /etc/passwd) -ge 1 ] || [ ${#USERNAME} -le 3 ] || [ ${#USERNAME} -ge 21 ]; do
    echo " "
    echo "Error: Username is in use or invalid.  Please select a different username."
    echo " "
    echo -n "Please enter the users requested username and press [ENTER]: "
    read USERNAME
done #USERNAME will be valid from this point

#ASK about the default shell now
echo -n "Enter the new shell if you would like one (currently $SHELL) or leave blank for the default and press [ENTER]: "
read tempSHELL
if [ ${#tempSHELL} -ge 1 ]; then
    SHELL="$tempSHELL"
    FINALCOMMAND=("${FINALCOMMAND[@]}" "-s" "$SHELL")
fi

#ASK about a different primary group
echo "Would you like to enter a non-default primary user group? Defaults to creating a new group that matches the username"
echo -n "Enter a new Primary Group or leave blank for the default and press [ENTER]: "
read newPrimaryGroup

if [ ${#newPrimaryGroup} -eq 0 ]; then
    FINALCOMMAND=("${FINALCOMMAND[@]}" "--user-group")
else
    if [ $(grep -c "^${newPrimaryGroup}" /etc/group) -ge 1 ]; then
        FINALCOMMAND=("${FINALCOMMAND[@]}" "-g" "$newPrimaryGroup")
    else
        echo "Invalid group specified reverting to default!"
        FINALCOMMAND=("${FINALCOMMAND[@]}" "--user-group")
    fi
fi

#ASK about additional groups
echo -n "Would you like the new user to be a part of any additional groups?  Leave blank if no additional groups are needed or enter additional groups in the format of GROUP1,GROUP2,... (NO SPACES) and press [ENTER]: "
read extraGroups
#remove spaces if the user entered any
extraGroups="${extraGroups//[[:space:]]}"
FINALEXTRAGROUPS=''
IFS=, read -a TEMP <<< "$extraGroups"
for g in "${TEMP[@]}"; do
    if [ $(grep -c "^${g}" /etc/group) -ge 1 ]; then
        FINALEXTRAGROUPS="$FINALEXTRAGROUPS,$g"
    else
        echo "$g is invalid user will not be added..."
    fi
done

if [ ${#FINALEXTRAGROUPS[@]} -ge 1 ]; then
    FINALCOMMAND=("${FINALCOMMAND[@]}" "-G" "${FINALEXTRAGROUPS:1}")
fi


#ASK about the home directory
echo -n "Would you like to enter a new home directory for the user?  Leave blank to use the default of $HOME/$USERNAME or enter your own and press [ENTER]: "
read NEWHOME

if [ ${#NEWHOME} -ge 1 ]; then
    FINALCOMMAND=("${FINALCOMMAND[@]}" "-d" "$NEWHOME")
fi

#ADD the username to the command
FINALCOMMAND=("${FINALCOMMAND[@]}" "$USERNAME")

#PASSCOMMAND="sudo passwd $USERNAME"

#ADD THE USER
echo "useradd ${FINALCOMMAND[@]}"

useradd "${FINALCOMMAND[@]}"

passwd "$USERNAME"

chfn "$USERNAME"

注: 新しいバージョンの bash では、 += を使用して値を配列に追加できます (ARRAY+=("value") など)。

また、追加の設定により、この方法でコードをさらに改善しますが、それはまだ最善ではありません。

#!/bin/bash

shopt -s extglob

# Check if running as root.
if [[ "$(id -u)" != 0 ]]; then
    echo "This script must be ran as root."
    exit 1
fi

# Initialize useradd command variable.
USERADDCOMMAND=("useradd" "-m")

# Import useradd defaults.
. /etc/default/useradd

# Get the new user's name.
#echo -n "Please enter the users First and Last Name and press [ENTER]: "
#read NAME

# Get the new users username.
echo "The username must be 4-20 characters."
while :; do
    read -p "Please enter the user's requested username and press [ENTER]: " USERNAME
    [[ ${#USERNAME} -ge 4 && ${#USERNAME} -le 20 && $USERNAME == +([[:alpha:]])*([[:alnum:]_-]) ]] || {
        echo "Error: Username is invalid. Please enter a different username."
        continue
    }
    [[ $(grep -c "^${USERNAME}:" /etc/passwd) -ge 1 ]] && {
        echo "Error: Username is in use. Please enter a different username."
        continue
    }
    break
done

# Ask about the default shell.
read -p "Enter the new shell if you would like one (currently $SHELL) or leave blank for the default and press [ENTER]: " SHELL_
if [[ ${#SHELL_} -ge 1 ]]; then
    USERADDCOMMAND=("${USERADDCOMMAND[@]}" "-s" "$SHELL_")
else
    # We use this if we really are to use SHELL specified in $SHELL but it still needs further workarounds like checking if $SHELL is valid. Those could be easily done but it depends if this one's really necessary.
    #USERADDCOMMAND=("${USERADDCOMMAND[@]}" "-s" "$SHELL")
    :
fi

# Ask about a different primary group.
echo "Would you like to enter a non-default primary user group? Defaults to creating a new group that matches the username."
echo -n "Enter a new Primary Group or leave blank for the default and press [ENTER]: "
read NEWPRIMARYGROUP

if [[ ${#NEWPRIMARYGROUP} -eq 0 ]]; then
    USERADDCOMMAND=("${USERADDCOMMAND[@]}" "--user-group")
else
    if [[ $(grep -c "^${NEWPRIMARYGROUP}" /etc/group) -ge 1 ]]; then
        USERADDCOMMAND=("${USERADDCOMMAND[@]}" "-g" "$NEWPRIMARYGROUP")
    else
        echo "Invalid group specified reverting to default!"
        USERADDCOMMAND=("${USERADDCOMMAND[@]}" "--user-group")
    fi
fi

# Ask about additional groups.
echo -n "Would you like the new user to be a part of any additional groups?  Leave blank if no additional groups are needed or enter additional groups in the format of GROUP1,GROUP2,... (NO SPACES) and press [ENTER]: "
read EXTRAGROUPS
# Remove spaces if the user entered any.
EXTRAGROUPS="${EXTRAGROUPS//[[:space:]]}"
FINALEXTRAGROUPS=''
IFS=, read -a TEMP <<< "$EXTRAGROUPS"
for G in "${TEMP[@]}"; do
    if [[ $(grep -c "^${g}" /etc/group) -ge 1 ]]; then
        FINALEXTRAGROUPS="$FINALEXTRAGROUPS,$G"
    else
        echo "$G is an invalid user and will not be added."
    fi
done
if [[ ${#FINALEXTRAGROUPS[@]} -ge 1 ]]; then
    USERADDCOMMAND=("${USERADDCOMMAND[@]}" "-G" "${FINALEXTRAGROUPS:1}")
fi

# Ask about the home directory
read -p "Would you like to enter a new home directory for the user?  Leave blank to use the default of $HOME/$USERNAME or enter your own and press [ENTER]: " NEWHOME
if [[ ${#NEWHOME} -ge 1 ]]; then
    USERADDCOMMAND=("${USERADDCOMMAND[@]}" "-d" "$NEWHOME")
fi

# Add the username to the command
USERADDCOMMAND=("${USERADDCOMMAND[@]}" "$USERNAME")

# Add THE USER
echo "> ${USERADDCOMMAND[*]}"
"${USERADDCOMMAND[@]}"

echo "> passwd $USERNAME"
passwd "$USERNAME"

echo "> chfn $USERNAME"
chfn "$USERNAME"  # -f "$NAME"
于 2012-11-03T17:10:00.780 に答える
2

If the man -s8 useradd does not mention --user-group option available to use, then -U will not work. There's still another solution worth trying:

The default behavior (if the -g, -N, and -U options are not specified) is defined by the USERGROUPS_ENAB variable in /etc/login.defs.

Another way is, you have to chain the useradd command with a groupadd command with the same username supplied as parameters to both the commands.

EDIT: This must work. First create the group and then create the user and add this new user to the group. Since, you are doing this in a script this should do the job very well.

Do this:

groupadd jaredm2
useradd -m -g jaredm2 jaredm2

Instead of this:

useradd -m --user-group jaredm2

Note that certain other programs which would've been installed in your OS, may have changed your binary or access to it or even created an alias for it. Your which output suggests that it is linked to the useradd binary in bin directory, precisely where it should be.

So I guess:

  • the binary might have been changed or replaced by a process, by package installers or something else
  • there's some mismatch between the binary version and the man page version(most likely if you have upgraded your OS improperly, at some point of time)

I think, the only solutions would be using the above pair of commands or changing the useradd binary you are using manually.

于 2012-10-25T06:22:39.390 に答える
1

デバッグ コンテンツの更新内容から判断すると、投稿したスクリプトとは異なる操作を行っているようです。

とにかく、デバッグ出力から、二重引用符を使用して adduser コマンドを実行しようとしていると思われます

"$FINALCOMMAND"

または、「そのようなファイルまたはディレクトリはありません」というエラーメッセージをトリガーする唯一の状況であるように思われるため、バッククォートで囲まれている可能性もあります。

二重引用符を取り除くと、問題が解決するはずです。

p/s : 実際に出力を使用していない限り (テストや変数への割り当てなど)、コマンド置換 ( ``) を使用しないでください。そうしないと、このようなことが起こる可能性があります

$ `echo Just saying hi`
Just: command not found
于 2012-10-30T13:00:14.873 に答える
0

スクリプトのバグを修正しました。IFS="," の行を削除するだけです。

環境変数 IFS (Internal Field Separator) の誤用です

スクリプトは次のようになります。

#!/bin/bash
#Add a new user

FINALCOMMAND="-m"

#import useradd defaults...
. /etc/default/useradd

#Check if running as root
if [ "$(id -u)" != "0" ]; then
    echo "This script must be ran as root"
    exit 1
fi

#Get the new users Name
#echo -n "Please enter the users First and Last Name and press [ENTER]: "
#read Name

#Get the new users username
echo "The username must be 4-20 characters."
echo -n "Please enter the users requested username and press [ENTER]: "
read USERNAME
while [ $(grep -c "^${USERNAME}:" /etc/passwd) -ge 1 ] || [ ${#USERNAME} -le 3 ] || [ ${#USERNAME} -ge 21 ]
do
    echo " "
    echo "Error: Username is in use or invalid.  Please select a different username."
    echo " "
    echo -n "Please enter the users requested username and press [ENTER]: "
    read USERNAME   
done #USERNAME will be valid from this point

#ASK about the default shell now
echo -n "Enter the new shell if you would like one (currently $SHELL) or leave blank for the default and press [ENTER]: "
read tempSHELL
if [ ${#tempSHELL} -ge 1 ]; then
    SHELL="$tempSHELL"
    FINALCOMMAND="$FINALCOMMAND ""-s $SHELL"
fi

#ASK about a different primary group
echo "Would you like to enter a non-default primary user group? Defaults to creating a new group that matches the username"
echo "Enter a new Primary Group or leave blank for the default and press [ENTER]: "
read newPrimaryGroup

if [ ${#newPrimaryGroup} -eq 0 ]; then
    FINALCOMMAND="$FINALCOMMAND --user-group"
else
    if [ $(grep -c "^${newPrimaryGroup}" /etc/group) -ge 1 ]; then
        FINALCOMMAND="$FINALCOMMAND -g $newPrimaryGroup"
    else
        echo "Invalid group specified reverting to default!"
        FINALCOMMAND="$FINALCOMMAND --user-group"
    fi
fi
#useradd -m --user-group jaredm2
#ASK about additional groups
echo "Would you like the new user to be a part of any additional groups?  Leave blank if no additional groups are needed or enter additional groups in the format of GROUP1,GROUP2,... (NO SPACES) and press [ENTER]: "
read extraGroups
#remove spaces if the user entered any
extraGroups="${extraGroups//[[:space:]]}"
FINALEXTRAGROUPS=""
#IFS=","
for g in $extraGroups
do
    if [ $(grep -c "^${g}" /etc/group) -ge 1 ]; then
        FINALEXTRAGROUPS="$FINALEXTRAGROUPS,$g"
    else
        echo "$g is invalid user will not be added..."
    fi
done
FINALEXTRAGROUPS=$(echo "$FINALEXTRAGROUPS" | tail -c +2)
if [ ${#FINALEXTRAGROUPS} -ge 1 ]; then
    FINALCOMMAND="$FINALCOMMAND -G $FINALEXTRAGROUPS"
fi

#ASK about the home directory
echo "Would you like to enter a new home directory for the user?  Leave blank to use the default of $HOME/$USERNAME or enter your own and press [ENTER]: "
read NEWHOME

if [ ${#NEWHOME} -ge 1 ]; then
    FINALCOMMAND="$FINALCOMMAND -d $NEWHOME"
fi

#ADD the username to the command
FINALCOMMAND=`echo "$FINALCOMMAND $USERNAME" | sed 's/ *$//g' | sed 's/^ *//g'`
echo "useradd $FINALCOMMAND"
#PASSCOMMAND="sudo passwd $USERNAME"
#ADD THE USER
useradd $FINALCOMMAND

passwd $USERNAME

chfn $USERNAME
于 2012-11-02T15:14:16.100 に答える