web-dev-qa-db-ja.com

id -u $ varは、$ varに値があるかどうかにかかわらず、同じ出力を提供します

私は、ユーザーがスクリプトに存在することを確認するための最良の解決策を見つけながら、新しいDebianインストールを構成するスクリプトを書いています。私が見つけた最良の方法は、奇妙な出力を与えてくれます。

問題:

id -u $varおよびid -u $varsomevarに値(ユーザー名)があり、varsomeに値がない場合でも、同じ出力を返します

[19:49:24][username] ~ ~↓↓$↓↓ var=`whoami`
[19:53:38][username] ~ ~↓↓$↓↓ id -u $var
1000
[19:53:42][username] ~ ~↓↓$↓↓ echo $?
0
[19:53:49][username] ~ ~↓↓$↓↓ id -u $varsome
1000
[19:09:56][username] ~ ~↓↓$↓↓ echo $?
0
[20:10:18][username] ~ ~↓↓$↓↓ bash --version
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2016 Free Software Foundation, Inc.
Licens GPLv3+: GNU GPL version 3 eller senere <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[20:27:08][username] ~ ~↓↓$↓↓ cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 9 (stretch)"
NAME="Debian GNU/Linux"
VERSION_ID="9"
VERSION="9 (stretch)"
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

私はstackoverflowでこの質問からコマンドを取得しました: ユーザーが存在するかどうかを確認してください

質問:

  • ここで何が起きてるの?
  • スクリプト内にユーザーが存在することを確認するためのより良い方法はありますか?
  • スクリプト上のポインタは高く評価されています
3

変数展開が引用されていないため、$varsomeが展開された結果として生じる空のWordは完全に削除されます。

取得した引数の数を出力する関数を作成し、引用符で囲まれた場合と引用符で囲まれていない場合を比較してみましょう。

$ args() { echo "got $# arguments"; }
$ var=""
$ args $var
got 0 arguments    
$ args "$var"
got 1 arguments

idの場合も同じことが起こります。varが空の場合のid -u $varid -uとまったく同じです。 idにはユーザー名が表示されないため、デフォルトでは現在のユーザーの情報が出力されます。

"$var"を引用すると、結果は異なります。

$ var=""
$ id -u "$var"
id: ‘’: no such user

これを修正すると、idを使用してユーザーが存在するかどうかを確認できます。 (ただし、ここでは出力は必要ないので、リダイレクトしてください。)

check_user() { 
    if id -u "$1" >/dev/null 2>&1; then
        echo "user '$1' exists"
    else
        echo "user '$1' does not exist"
    fi
}
check_user root
check_user asdfghjkl

これにより、user 'root' existsuser 'asdfghjkl' does not existが出力されます。


これは、引用符で囲まれていない変数の予期しない単語分割から生じる通常の問題の逆です。しかし、基本的な問題は同じであり、ここでの答えの半分が言うことによって修正されます:常に変数展開を引用します(引用されていない動作が必要であることがわかっている場合を除く)。

見る:

9
ilkkachu

コマンド_id -u_は、現在のユーザーのIDを提供します。コマンド_id -u user_は、そのユーザーのIDを提供します。

今あなたの例では、あなたは使用します

_var=`whoami`
id -u $var
_

コマンドwhoamiは、現在のユーザーを返します。したがって、_id -u current_user_は現在のユーザーのIDを返し、_id -u_も現在のユーザーのIDを返します。

編集

バックティックは非推奨であることに注意してください。代わりに$(whoami)を記述することをお勧めします。次に例を示します。

_var=$(whoami)
id -u $var
_
1
RalfFriedl