首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基本Linux脚本编写

基本Linux脚本编写
EN

Stack Overflow用户
提问于 2021-10-14 02:52:30
回答 3查看 141关注 0票数 0

在bash脚本中执行我的第一步。到目前为止,我已经完成了5/7的练习,陷入了最后两个阶段,我无法找到解决这个问题的方法。

下面是对请求的练习的更好的转换,应该使用sed、echo、cat、uniq、tr、grep、wc等简单命令来解决相同的问题:

编写命令行,该命令行显示默认shell是计算机上可用shell之一的用户数量。在执行命令时,对于每个shell,我们将得到如下相同形式的结果:

  • 0用户对于shell / bin / sh
  • 11用户对于shell / bin / bash
  • 0用户对于shell / usr / bin / sh
  • 0用户对于shell / usr / bin /bash

f 211

@托德

今天早上我做了,你的grep重定向输入给了我这个想法。我就是这样做的:

  • result=$(grep -of <(echo $SHELL) /etc/passwd | uniq -c)
  • count=$(echo $result I awk -F” “ '{print $1}')
  • shell=$(echo $result | awk -F” “'{print $2}')
  • echo $result | while read i; do
  • echo $count utilisateurs ont pour shell $shell
  • done
EN

回答 3

Stack Overflow用户

发布于 2021-10-14 10:56:39

Unix实用程序和Bash过程替换

在巴斯,有很多方法可以做到这一点。然而,从实际的角度来看,您并不需要Bash本身来解决这个问题。标准*nix工具会做得很好,只要您正确地将它们连接起来。例如,如果输出的特定格式不是要点:

代码语言:javascript
复制
$ grep -of <(grep '^/.*$' /etc/shells) /etc/passwd | sort | uniq -c
   11 /bin/bash
    8 /bin/sh
    4 /usr/local/bin/fish

这基本上是从/etc/shell中获取shell,然后grep将该输出作为一个文件来读取表达式,以便与/etc/passwd匹配。然后,它将结果传送到sort和uniq实用程序,以计数出现的情况。它依赖于进程替换,而进程替换并不是所有shell都有相同的方式或表示方式,但是您的问题是用Bash标记的,所以避免使用Bashism并不是一个主要问题。

然而,由于并非所有shell都具有Bash所做的进程替换重定向,因此这样的解决方案并不是跨不同shell 100%可移植的。通常有类似的方法,但有时跨系统和shell的可移植性非常重要。无论如何,这表明grep、管道和进程替换是多么强大。

一旦您有了原始数据,您就可以使用printf、awk甚至sed格式化输出,如果您想要使用不同的格式。但是,如果重点是计算shell的使用情况,在Bash或zsh中这样做是一种简单的方法。

更便携的选择

一个更复杂(但也更易于移植)的选择是使用xargs作为管道的核心元素。例如:

代码语言:javascript
复制
$ grep -o '^/.*$' /etc/shells |
    xargs -I{} -L1 -- sh -c 'echo "{}"; grep -Fc "{}" /etc/passwd' |
    xargs -n2
/bin/bash 11
/bin/csh 0
/bin/ksh 0
/bin/sh 8
/bin/tcsh 0
/bin/zsh 0
/usr/local/bin/fish 4

这将找到/etc/shell中的所有shell,将它们一次一个地传递给Bourne脚本,以打印shell的路径,并让grep的固定字符串匹配器计数/etc/passwd中出现的情况,然后再将输出输送到xargs,每次将行连接回两个。

这种方法的主要好处是它将列出所有shell,无论是否有人使用它们。如果希望在shell名称之前列出数字,甚至可以将最后一行更改为tac | xargs -n2

票数 1
EN

Stack Overflow用户

发布于 2021-10-14 04:05:24

这就是我如何理解你的问题,一种使用数组的方法,包括关联数组。

代码语言:javascript
复制
#!/usr/bin/env bash

declare -A Shell_and_Users

while IFS=: read -ra lines; do
  login_shell="${lines[-1]}"
  ((Shell_and_Users["$login_shell"]++))
done < /etc/passwd

要检查关联数组Shell_and_Users的值,请运行:

代码语言:javascript
复制
declare -p Shell_and_Users

现在循环遍历关联数组以打印所需的输出。

代码语言:javascript
复制
for i in "${!Shell_and_Users[@]}"; do
  printf -- '- %d users have shell %s\n' "${Shell_and_Users[$i]}" "$i"
done

如果不是这样,那么编辑问题并添加更多细节,如果文件/etc/shells应该解析/涉及,因为上面的解决方案永远不会打印0 users

票数 0
EN

Stack Overflow用户

发布于 2021-10-14 05:44:08

假设可以使用awk,您可以尝试以下方法

代码语言:javascript
复制
$ cat awk.script
#!/usr/bin/env awk -f

BEGIN {
    FS=":"
} $NF=="/bin/bash" {
    count_bash++
    bash=$NF
} $NF=="/usr/bin/bash" {
    count_bash2++
    bash2=$NF
} $NF=="/bin/sh" {
    count_sh++
    sh=$NF
} $NF=="/usr/bin/sh" {
    count_sh2++
    sh2=$NF
} END {
    print count_bash " users have a shell for "bash "\n" \
          count_bash2" users have a shell for "bash2 "\n" \
          count_sh " users have a shell for "sh "\n" \
          count_sh2" users have a shell for "sh2 "\n" \
}

这将提供与预期输出类似的输出,但是,如果shell没有使用,您将得到一个没有值或路径的空输出,这可能并不理想。

输出

代码语言:javascript
复制
$ awk -f awk.script /etc/passwd
24 users have a shell for /bin/bash
 users have a shell for
2 users have a shell for /bin/sh
 users have a shell for
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69564539

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档