【问题标题】:Scripting - Iterating Numbers Using a While Loop (newusers command)脚本 - 使用 While 循环迭代数字(newusers 命令)
【发布时间】:2017-12-20 01:15:52
【问题描述】:

我正在编写一个脚本,我想在数字 1 到 15 之间进行迭代,但希望它显示为 01 02 03 ... 13 14 15。基本上我要做的是使用 newusers 添加 15 个用户命令并将此脚本用作命令的

pw_name:pw_passwd:pw_uid:pw_gid:pw_gecos:pw_dir:pw_shell

基本上,当我使用参数运行脚本时,它应该是这样的 =

cstuser01:EzVlK9Je8JvfQump:1001:1001:CST8177 user:/home/cstuser01:/bin/bash
cstuser02:EsKOfvhgnWpiBT6c:1002:1002:CST8177 user:/home/cstuser02:/bin/bash
cstuser03:qzQuR5vRgxdzY6dq:1003:1003:CST8177 user:/home/cstuser03:/bin/bash

我得到了大部分工作,但我收到以下错误:

./15users.sh: 57: ./15users.sh: 非法编号:08

到目前为止,这是我的脚本(我取出了几个带有错误检查的部分)=

#!/bin/sh -u
PATH=/bin:/usr/bin ; export PATH
umask=022

#num=1 (this variable is needed depending on which loop I use below)
user=$prefix"user"
uid=1001
gid=$uid
home=/home/$user
shell=/bin/bash

#echo "pw_name:pw_passwd:pw_uid:pw_gid:pw_gecos:pw_dir:pw_shell"
#PASSWD=$(openssl rand -base64 12)

我最初有这个但遇到了一些问题:

while [ $NUM -le 15 ] ; do
       if [ $NUM -lt 10 ] ; then
               NUM=0$NUM
       fi
       echo "$USER$NUM:$(openssl rand -base64 12):$UID:$GID:$GECO:$HOME$NUM:$SHELL"
       UID=$(( UID + 1 ))
       GID=$(( GID + 1 ))
       NUM=$(( NUM + 1 ))
done

我的一个朋友建议这个,它工作得很好。但我试图在未来证明这件事。如果我要添加 100 或 1,000 个用户怎么办?

for NUM in 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 ; do
       echo "$USER$NUM:$(openssl rand -base64 12):$UID:$GID:$GECO:$HOME$NUM:$SHELL"
done

这不起作用:

for num in {01..15} ; do
    i=09
    echo "$(( 10#$num + 1 ))"
    10
done

然后我尝试这个得到一个语法错误=

./15users.sh: 50: ./15users.sh: 语法错误:循环变量错误

for (( num=1; num<=15; num++ )) ; do
    printf "%02d\n" $num
done

我也试过了,但是 seq 垂直打印而不是水平打印:

#iterate=$(seq -w 1 15)
for $iterate ; do
       echo "$user$num:$(openssl rand -base64 12):$uid:$gid:$geco:$home$num:$shell"
done

【问题讨论】:

    标签: linux bash shell centos7


    【解决方案1】:
    1. 要循环 01 到 15,使用大括号扩展要简单得多:

      $ for num in {01..15}; do echo "$num"; done
      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      13
      14
      15
      
    2. 在 bash 中,默认情况下,以 0 开头的数字是八进制的。由于0809 作为base-8 数字是非法的,它们会导致错误。为避免这种情况,请明确指定基数:

      $ i=09; echo $(( 10#$i + 1 ))
      10
      

      表达式 10#$i 告诉 bash 将 $i 解释为以 10 为底的数字。

    3. 为您的脚本变量使用全部大写字母。系统使用全部大写,您不想意外覆盖系统变量。

      对于UID,它是一个只读 bash 变量。您的脚本尝试分配UID 将失败。为您的脚本变量使用小写或混合大小写。

    4. 另一个全大写问题的例子是$HOME。请注意,以下代码有效:

      $ openssl rand -base64  12
      1bh9+dp+Ap7xFIBB
      

      但以下失败:

      $ (HOME=/home/user; openssl rand -base64  12)
      zceZeWsQGpohTPvv
      unable to write 'random state'
      

      显然,openssl 期望拥有对$HOME 的写访问权限。 将HOME 分配给不存在的目录会导致错误。

      因此,再次不要将脚本变量全部大写。

    【讨论】:

      【解决方案2】:

      我不会尝试诊断您的错误消息,但您过于复杂了您想要实现的目标。

      for i in {01..15}; do echo $i; done
      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      13
      14
      15
      

      【讨论】:

      • 对于 {01..15} 中的 num ; do num=01 echo "$(( 10#$num + 1 ))" 10 完成
      • @Darren,您能否编辑您的原始帖子并添加修改后的脚本?很难理解你改变了什么以及它以什么方式失败......
      • 好了,我添加了上面的更改
      【解决方案3】:

      Bash 也支持 C 风格的循环:

      $ for (( i=1; i<=15; i++ )); do printf "%02d\n" $i; done
      01
      02
      03
      04
      05
      06
      07
      08
      09
      10
      11
      12
      13
      14
      15
      

      只需使用带有标志的printf 来打印前导0,您就有了输出。

      【讨论】:

      • 您的代码中似乎省略了分号。这工作正常。
      【解决方案4】:

      由于尚未提及:

      seq -w 1 15
      
      seq -w 1 15 | while read num; do echo "n=$num"; done
      

      【讨论】:

      • 我怎么把这是一个for循环
      猜你喜欢
      • 2013-09-09
      • 1970-01-01
      • 2020-09-21
      • 2015-08-20
      • 2013-11-30
      • 1970-01-01
      • 2019-12-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多