特定のシェルを使用しているユーザー数を出力するwhileループBashスクリプト


0

そこで、/ etc / passwdから入力を受け取り、bash、nolongin、csh、およびkshを使用しているユーザー数を出力する、bashスクリプトのwhileループ関数を作成しようとしています。私は猫とカットを使うことになっていると思います。そして私は、ユーザーが使用するシェルのタイプが7番目のフィールドにあることを知っています。

シェルの種類ごとに変数を作成し、その特定のシェルを使用するユーザーが見つかるたびに変数を増やす必要があると考えるのは正しいですか。

これまでのところ、これは私が持っているコードですが、何らかの理由でそれは最後のifステートメントを出力するだけです..

declare -i bash;
declare -i nologin;
declare -i csh;
declare -i ksh;

bash=0;
nologin=0;
csh=0;
ksh=0;
cat /etc/passwd | cut -d: -f7 $line | while read line;
do
    if [ $line == "bash" ]
            then
                    bash=bash+1;
    else  fi [ $line == "/sbin/nologin" ]
            then
                    nologin=nologin+1;
    else fi [ $line == "chs" ]
            then
                    chs=chs+1;
    else
            then
                    ksh=ksh+1;
    fi
done

更新:これまでのところ、私はコードを変更し、持っているものを更新しました。それはループしてif文の正しい部分を出力しますが、私は自分の持っている変数をインクリメントしようとしています


あなたはひどいスタートを切っています。 bash(1)を読んでやり方を確認 if - then - else ブロック(も見て case そしてそれがあなたにとってより理にかなっているかどうかについて考えてください)。シェル変数を使った算術演算の方法も調べてください。そしてcut(1)を読んで、コマンドラインでデータを処理する方法を確認してください。そしてもしあなたが道を見つけたら、私に知らせてください。私は何も知らないからです(ヒントヒント)。最後に、について学ぶ UUoC
Scott

最初に、私はelse節でifをfiに​​置き換えます
Archemar

私が今したのは、$ lineを使ってcat / etc / passwdをカットに入れることです。そして$ lineをechoすると、ifステートメントで比較する必要があるデータを吐き出します。問題は、その$行を必要な特定のものと比較する方法です。例えば、$行が "/ bin / bash"の場合、bash変数を1だけ増やすことになっています。ここでは、ifステートメントのどの部分を通過することを選択し、常に最初の部分を通過するかを確認しますif文は、それが真実であるかのようにそれを通過します。
DoctorWho22

回答:


1

これが私のバージョンです:

#!/bin/bash

bash=0;
nologin=0;
csh=0;
ksh=0;

while read line;
do
    innerline=$(echo "$line"| cut -d: -f7)

    if [[ $innerline == "/bin/bash" ]]
    then
                    bash=$(echo "$bash+1"|bc);
    elif [[ $innerline == "/sbin/nologin" ]]
    then
                    nologin=&(echo "$nologin+1"|bc);
    elif [[ $innerline == "/bin/csh" ]]
    then
                    csh=$(echo "$csh+1"|bc);
    else
                    ksh=$(echo "$ksh+1"|bc);
    fi
done < /etc/passwd

echo "$bash $nologin $csh $ksh"

値を増やすには、計算ジョブをに渡します。 bc これは小さな電卓ユーティリティです。

それがあなたのために働くかどうか私に知らせてください。

正直に言うと、私はこの解決策が本当に嫌いだと言わなければなりません。 whileループは不要なので@Natのソリューションをお勧めしますが、whileループは必ず存在する必要があると明確に述べたため、ここにあります。

PS。これはひどい考えです。

else
                        ksh=$(echo "$ksh+1"|bc);

すべての未知の/比類のないシェルが ksh


それを考慮に入れてはいけません $line 保持するかもしれない /bin/bash ではない bash ?多分 $(basenamr $line)
Archemar

1
@ Archemar、確かに!他にもシェルがあります - 例えば/ bin / false。彼が取り組んでいるのに偽の/ etc / passwordがあるかもしれないので、私はその問題でOPスクリプトを修正していません。スクリプト操作、bashキーワード(elif)、冗長な fi、大括弧、そして彼がオカレンスを計算する方法を提供します。
mnmnc

@ Archemar、検討後、OPだけでなくコミュニティにも利益をもたらすはずなので変更しました。私は適切なスクリプトがマッチングパターンとして一定のシェルパスを持つべきではないと思いますが。スクリプトは最初の実行で/ etc / passwdを解析して固有のシェルを収集し、次に2番目の実行で出現回数を計算します。
mnmnc

ksh valueはデフォルトの大文字と小文字を区別します。
Archemar

3

これが宿題なのかわからないので、これは要件に合わないかもしれませんが、実際にこれを実行するためのスクリプト全体は必要ありません。これはワンライナーで行うことができます。

cat /etc/passwd | cut -d ':' -f 7 | sort | uniq -c

出力は次のようになります。

  4 /bin/bash
  6 /sbin/nologin
  4 /usr/bin/csh
 13 /usr/bin/ksh

これがどのように機能するのか uniq(1) フィルタ 隣接 INPUT "からの行のマッチングなど -c オプションは隣接する行を数えるので、一致するすべての行が隣接するように最初に行をソートする必要があります。


それは私がUnixクラスのために取り組んでいるものなので、whileループ関数を作成することになっています。
DoctorWho22

私はほとんどうまく動いています。変数を増やす方法を見つける必要があります。
DoctorWho22

0

ある考え

 cat /etc/passwd | while read line;

並ぶ

 tmpfoo:x:1004:1005:utilisateur test sudo:/home/tmpfoo:/bin/bash

それから、

  cut -d: -f7 $line == "bash"

に評価されます

 cut -d: -f7 tmpfoo:x:1004:1005:utilisateur test sudo:/home/tmpfoo:/bin/bash == "bash"

cutは3つのファイルtmpfoo:x:1004:1005:utilisateur、testおよびsudoを検索します。

プレゼントとして、このサンプルループをお試しください

cat /etc/passwd |  cut -d: -f7 | while read line;
do
    echo $line
done

0

私は使用することになっていると思います cat そして cut

それは私がUnixクラスのために取り組んでいるものなので、whileループ関数を作成することになっています。

もちろん、UNIXバージョン7のパスワードファイルのように、レコードが改行で区切られ可変長でフィールドが単一の区切り文字で区切られる可変長のファイルは、次のようなものです。 awk で優れています。それで、前述の制約なしにここに来る人々の利益のために、ここに awk ワンライナー:

awk -F : '{x[$7]++;} END {for (k in x) print k": "x[k]}' /etc/passwd

ここで学ぶべき教訓は以下のとおりです。

  • UNIXには、歴史的なデータベースファイルフォーマットに合わせた特別なツールがあります。この特定の種類のファイル形式は、扱うのが簡単です。 awk
  • 使う必要はありません catインストラクターの言うことにもかかわらず。 ☺コマンドパイプラインの使い過ぎなどがあります。の中に while ループケースの単純なリダイレクトは、mnmncの答えのようになります。の場合 awk処理するファイルは単に引数として与えられます。
  • while ここでのループは、もちろん、 awk プログラム。その主な機能は、入力ファイル内のすべてのレコードを順番に読み取り処理することです。
  • シェルの種類ごとに変数を作成し、その特定のシェルを使用するユーザーが見つかるたびにそれを増分する必要があると考えるのは正しいですか。
    はい、そして awk ここでワンライナーはいわゆる 連想配列 x 変数。の第二部 awk スクリプトは、に通常の方法を示しています 繰り返す そのような連想配列の内容最初の部分は単に増分です( ++ レコードのフィールド7でインデックス付けされた、配列内の1つの要素の値の後置演算子 awk として利用可能になります $7

    ご了承ください Bourne Againシェルスクリプトで連想配列を作成することもできます。 制約のある答えのためにこのテクニックをスクリプトに適応させる。あなたが使用することに制限されるかもしれません while ループ;しかし だれも使用することを制限していません if

参考文献


問題は、与えられた割り当てがcatとcutを使って特定のユーザーがどのシェルを使っているかを判断することです。
DoctorWho22

これは、2番目と4番目の箇条書きで説明されています。
JdeBP
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.