多くの場合、bash スクリプト内またはスクリプト自体内で直接 sudo を使用してコマンドを実行する必要がありますが、これにより一連の問題が発生します。 たとえば、sudo を使用する場合、ユーザー フォルダーを参照するスクリプト内の変数 ~ または $HOME は、/home/pi などの実際のユーザー フォルダーを指す必要がありますか、それともスーパー管理者のユーザー フォルダー /root/ を指す必要がありますか? 実際には /root/ フォルダーを指していますが、これは絶対に望ましくありません。しかし、プログラムのインストールなど、多くのコマンドでは sudo を使用する必要があります。どうすればよいでしょうか? まず、私の経験を共有させてください。コマンドライン権限の実行は、パフォーマンスの観点から次の 5 つの状況に分けられます。
これらの 4 つの状況では、多くの変数と環境変数が混同されることがよくあります。 (混乱とはコンピュータではなく、私たち自身を指します) また、ちょっとしたヒントがあります。 ~ 変数は現在のユーザーのディレクトリを指すことは誰もが知っています。実際、~abc 形式の変数は、指定されたユーザーのユーザー ディレクトリを指すことができます。たとえば、~pi は /home/pi を指し、~ubuntu は /home/ubuntu を指します。 私たちの考えを明確にしましょう: ./test.sh など、普通にスクリプトを実行する場合は問題ありません。sudo apt-get update など、スクリプト内に sudo が登場しても問題ありません。 実際のユーザーが pi で、HOME ディレクトリが /home/pi であるとします。ここで、sudo ./test.sh の実行モードで正しいソリューションを見つけたいと思います。 # (非推奨!) $ だれだ >>> ルート # whoami とは異なり、ローカルおよび ssh 経由でログインしているすべてのユーザーを含め、現在コンピューターにログインしているユーザーを表示できます。$ who am i >>> 一部のマシンでは空と表示されます >>> Mac では次のように表示されます: pi ttys001 11 月 26 日 16:57 # whoami と同等です (非推奨!) $ エコー $USER >>> ルート # ユーザーのホーム ディレクトリの場所 (信頼性が低く、推奨されません) $HOMEをエコーする >>> /ルート $ ユーザーのホーム ディレクトリの場所。$HOME と同等です (推奨されません) $ エコー ~ >>> /ルート # 環境変数LOGNAMEを直接使用する $ echo $LOGNAME >>> ルート # 環境変数LOGNAMEを明示的に呼び出す $ printenv ログ名 >>> ルート # SUDO_USER は、ルートの ENV 内の環境変数です。 # 同時に、一般ユーザーには env がなく、それを表示できるのは root ユーザーだけです $ sudo echo $SUDO_USER >>> 円周率 # 呼び出し環境変数 SUDO_USER を表示します (推奨されません) # 結果から、スクリプトを sudo として実行した場合でも、スクリプトに sudo を追加すると異なることがわかります。 $ printenv SUDO_USER >>> 円周率 $ sudo printenv SUDO_USER >>> ルート 上記のテストから、sudo を使用して bash スクリプトを実行すると、多くの変数が「信頼できない」ことがわかります。 Stackoverflow では、$SUDO_USER 環境変数を使用する傾向がより一貫しています。そして、テストでは、これは確かに最も「安定」しており、つまり、さまざまな権限や OS システム (sudo のあるシステムのみ) の下で一貫性を保つことができます。 ユーザー名がわかったので、~pi のようなコマンドを使用してホーム ディレクトリ /home/pi を取得できますが、 ここで再び問題が発生します。手動で入力すると、~pi の正しいアドレスを取得できますが、スクリプトは ~pi が何であるかを認識しません。せいぜい、変数ではなく文字列です。 この場合、~abc メソッドは使用できませんが、昔ながらの、決して混乱を招かないメソッドを使用します。 手動では、passwd を直接開いて表示できますが、スクリプトでは面倒です。最も便利な方法は、システム コマンド getent (Get Entries コマンド) を使用して、指定されたユーザーの情報を取得することです。 $ getent パスワード pi >>> pi:x:1000:1000:,,,:/home/pi:/bin/bash したがって、残っているのは /home/pi を削除することですが、これは cut を使用して簡単に削除できます。 全体のプロセスは次のようになります。 私=$SUDO_USER myhome=`getent passwd $me | cut -d: -f 6` /home/pi を正常に取得しました。 さらに一歩進んで、スクリプトが sudo として実行されない場合はどうなるでしょうか?現時点では、root ユーザーおよび一般ユーザーの環境変数には SUDO_USER 変数は存在しません。次に、判断のステップを追加する必要があります。 私=${SUDO_USER:-$LOGNAME} myhome=`getent passwd $me | cut -d: -f 6` つまり、SUDO_USER が空の場合、通常、$LOGNAME を使用して現在のユーザーを取得します。 $USER の代わりに $LOGNAME を使用しないのはなぜですか? USER はすべてのシステムで使用できるわけではありませんが、LOGNAME はすべての *nix システムで使用できます。 更新する 一部の OS では LOGNAME を正しく取得できないため、uid メソッドを使用してユーザー パスを取得します。 HOUSE=`getent passwd ${SUDO_UID:-$(id -u)} | cut -d: -f 6` 再度更新 MacOS には /etc/passwd がなく、ユーザー情報を取得するための getent passwd <UID> メソッドをサポートしていませんが、$USER および $HOME 変数の内容は sudo では変更されません。 次のように変更します。 HOUSE=${$(`getent passwd ${SUDO_UID:-$(id -u)} | cut -d: -f 6`):-$HOME} つまり、getent メソッドがコンテンツを取得できない場合は、$HOME の値が直接取得されます。 再度更新 bash は上記のネストされた三項式をサポートしていないため、分離する必要があります。 HOUSE="`cat /etc/passwd |grep ${SUDO_UID:-$(id -u)} | cut -d: -f 6`" 家=${家:-$ホーム} 何度も更新する ルートの場合、grep uid は passwd に 0 が含まれるすべての行に一致するため、次のように改善する必要があります。 HOUSE="`cat /etc/passwd |grep ^${SUDO_USER:-$(id -un)}: | cut -d: -f 6`" 家=${家:-$ホーム} 以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。 以下もご興味があるかもしれません:
|
>>: mysql5.7.19 winx64 インストールおよび構成方法のグラフィック チュートリアル (win10)
Bステーションでパスワードを入力するときに目を覆っているこの画像を見たことがある人もいると思いますこ...
antd-mobileをインストールするグローバル輸入 npm をインストール antd-mobil...
1. Dockerをインストールします。参考URL: Docker 入門インストールチュートリアル ...
目次forEach() メソッドjs の Array.forEach のループから抜け出す方法解決:...
目次MySQLを初期化するMySQL サービスをインストール + MySQL サービスを開始MySQ...
まず、Docker がインストールされたサーバーが必要です。 (私はすでにこれをサーバーにインストー...
3 つの属性 flex-grow、flex-shrink、flex-basis の機能は次のとおりで...
この記事では、クラス抽選アプレットを実装するためのJavaScriptの具体的なコードを参考までに紹...
目次1. JavaScriptを使用してQRコードを解析する1. QR コードとは何ですか? 2.q...
MySQL UNION 演算子このチュートリアルでは、MySQL UNION 演算子の構文と例を紹介...
チェックボックスやラジオボタンの使用を含むコードをコピーコードは次のとおりです。 <!DOCT...
目次序文1. DDL 1.1 データベース操作1.2 データテーブルの操作1.3 一般的なデータ型1...
パノラマビュー効果を見てみましょう: 住所を表示スクリーンショット: 体験してみると、周囲の環境がぐ...
この記事では、二次リンクを実現するためのReactの具体的なコードを参考までに共有します。具体的な内...
購入証明書Alibaba CloudのCloud Shield証明書サービスから購入できます。証明書...