web-dev-qa-db-ja.com

ユーザー名を入力として使用:ユーザーがログインしている場合、ユーザーに属する実行中のプロセスを表示します

ユーザーの名前をコマンドライン入力として使用するスクリプトを作成します。そのユーザーがログインしている場合、ユーザーが実行しているプロセスが表示されます。彼/彼女がログインしていない場合、スクリプトはこれに言及する必要があります。

私の試みは機能していません:

#!/bin/bash
echo "Who are you?"
read user
echo $user
name=$(whoami)
if[$user == $name]
then
  top -u $user
else
  echo "not logged in"
fi
2
rumana khanom

who -uコマンドを使用して、ログインしているユーザーをリストできます。次に、grepを使用して、出力で特定のユーザーを検索し、見つかった場合は成功して終了し、そうでなければ失敗して終了できます。 。

#!/bin/bash

read -p 'Enter username to check: ' user
if who -u | grep -q "^$user "; then
    top -u "$user"
else
    echo "User $user is not logged in"
fi

who -u | ...部分を短縮してくれた@dessertに感謝します!)

3
janos

私には、タスクを少し誤解しているように見えます。スクリプトはシステム管理者がユーザーをチェックするために使用するものだと思うので、「あなたは誰ですか?」、スクリプトを実行しているユーザーが自分のユーザー名を入力したことを確認することはあなたのスクリプトではありませんすることになっています!

janos 'answer および dessert's answer は、あなたが望むことを正確に行うと思いますが、より良い答えはありません。しかし、スクリプトをデバッグするためのいくつかのヒントがあります...

test aka [

Shellビルトインである[を使用しました。 help [を実行することでいくつかの情報を見ることができますが、その情報が示すように、それはtestコマンドのバージョンであり、help testの下に詳細情報があります。スクリプト(scriptという名前)を実行すると、次のエラーが表示されます。

script: line 6: if[zanna == zanna]: command not found
script: line 7: syntax error near unexpected token `then'
script: line 7: `then'

ifおよび[コマンドを引数から分離するために3つのスペースが必要でした。また、Sergiyが Bashバージョン4.4まで で指摘したように、==演算子はtestまたは[に存在しませんでした。 Ubuntu 16.04はBash 4.3を使用しています。 17.10にBash 4.4があります。次のように構文エラーを修正できます。

if [ "$user" = "$name" ]

また、そのテストを行うことにより、余分な変数の割り当てを避けることもできます。

if [ "$user" = "$(whoami)" ]

しかし、簡潔さは、特にシェルスクリプトでは常に明確さをもたらすわけではありません。さらに、これは本当にやりたいことではありませんスクリプトを実行するにはスクリプトをログインする必要があるため、スクリプトの構文的に正しいバージョンでも、ユーザーがユーザー名を正しく入力したかどうかを確認するだけで、タスクはそれを要求しません。

read

readはBash組み込みコマンドです。 help readを実行すると、その情報を取得できます。

readコマンドを使用するときは、おそらく-rオプションを使用して、入力のバックスラッシュがエスケープとして機能しないようにする必要があります。

また、ユーザープロンプトをechoingする代わりに、read-pオプションを使用し、-pの後にプロンプ​​トを記述して、より簡潔なスクリプトを作成できます。

echo "Who are we checking on? "
read -r user

と同じ

read -rp "Who are we checking on? " user

readは入力を変数REPLYに自動的に入れるため、変数に厳密に名前を付ける必要もありません。これをテストできます:

read -rp "Who are we checking on? "
echo "$REPLY"

もちろん、変数に名前を付けたいことがよくあります。これにはuserが良い選択だと思います。

if

ifもシェル組み込みコマンドであるため、help ifを実行することで確認できます。その後、コマンドをチェックし、thenブランチを実行しますそのコマンドの終了ステータスがゼロの場合(つまり、成功した)。 janos 'answer は、ifの終了ステータスを単に収集することにより、testまたは[なしでgrepを使用します。

who -u | grep -q "^$user "

who -uの出力を検索して、$user変数の値で始まる行があるかどうかを確認します。 ^は行の始まりであり、-qオプションは出力を抑制します。 grepの終了ステータスは、一致するものが見つかるとゼロになるため、$userが見つかると、then構造体のifブランチが実行されますが、grepが見つからない場合は、else構造体のifブランチが実行されます(存在する場合)。

デザートの答え はシェルのロジックのみを使用してコマンドの成功と失敗のアクションを定義します-ifさえもここでは必要ありません:)

test再び

終了ステータスのチェックで十分なので、[またはtestコマンドはまったく必要ないと思います。本当に使用したい場合は、次のようなものを使用できます

[ -n "$(w -h | grep "^$user ")" ]

コマンド置換全体を引用符で囲む必要があります。または、出力に複数の単語がある場合、[は引数が多すぎると文句を言います($userは1つの単語なので、grep -oを使用して出力することもできます一致のみ)。文字列が空でない場合、-nはtrueです。

who -uの代替はw -hです。どちらがより移植性があり、信頼性が高いかわかりません。 whoは、端末エミュレータごとに出力がわずかに異なることに気付きましたが、このスクリプトの動作を停止するほどの違いはありません。

引用

ほとんどの場合、スクリプト内で変数を引用して、それ以上の拡張を防ぎます。 Ubuntuでユーザーを作成するために使用するユーティリティでは、シェルが展開を実行する可能性のあるスペースまたはその他の文字を含むユーザー名を作成することはできません。したがって、このスクリプトで変数を引用することは厳密に必須ではないと思います。それでも、そのようなユーザー名が存在する可能性があり、引用符を外す必要のない変数を引用するのは良い習慣です。


完全を期すために、ここに[なしのバージョンを示します(本質的にはjanos 'と同じです):

#!/bin/bash

read -rp "Who are we checking on? "
if w -h | grep -q "^$REPLY "; then
    echo "here's what "$REPLY" is doing:"
    top -u "$REPLY"
else
    echo "looks like "$REPLY" is not logged in."
fi
3
Zanna