su コマンドエラー

su コマンドエラー

/etc/profileスクリプトを使用してファイル内の特定の行を変更するコマンドを作成していますが、Linuxの一部のバージョンではコマンドがアクティブにならない可能性があるため、実行時にスクリプトでコマンドを使用する必要がsudoあります。su

ファイルには/etc/profile次の行が含まれています。

if [ "`id -u`" = "0" ]; then
  echo $PATH | grep /usr/local/sbin 1> /dev/null 2> /dev/null
  if [ ! $? = 0 ]; then
    PATH=/usr/local/sbin:/usr/sbin:/sbin:$PATH
  fi
fi

だから私はこれをしました:

$ PROFILE="/etc/profile"

$ sed '/\"`id -u`\"/ s/^if/# if/g;/\"`id -u`\"/ s/$/\nif [[ \"\$(id -u)\" == \"0\" || \"\$(id -un)\" == \"\${HOME##*\/}\" ]]; then/g;' ${PROFILE}

# if [ "`id -u`" = "0" ]; then
if [[ "$(id -u)" == "0" || "$(id -un)" == "${HOME##*/}" ]]; then
  echo $PATH | grep /usr/local/sbin 1> /dev/null 2> /dev/null
  if [ ! $? = 0 ]; then
    PATH=/usr/local/sbin:/usr/sbin:/sbin:$PATH
  fi
fi

コマンドはファイルを変更するために正しく実行されているように見えますが、su -c次のように実行すると:

$ PROFILE="/etc/profile"

$ su -c "sed '/\"`id -u`\"/ s/^if/# if/g;/\"`id -u`\"/ s/$/\nif [[ \"\$(id -u)\" == \"0\" || \"\$(id -un)\" == \"\${HOME##*\/}\" ]]; then/g;' ${PROFILE}"

if [ "`id -u`" = "0" ]; then
  echo $PATH | grep /usr/local/sbin 1> /dev/null 2> /dev/null
  if [ ! $? = 0 ]; then
    PATH=/usr/local/sbin:/usr/sbin:/sbin:$PATH
  fi
fi

パスワードを要求して変数内のファイルを読み込みますが、行は変更しません$PROFILE。コマンドにどのような問題がありますかsu -c

答え1

気づく:すべてのコードはテスト済みです。Slackware64 15.0仮想マシンで。

文字通りの答え

@ilkkachuが指摘したように、コマンドの2番目の形式で(使用(1))二重引用符の中に一重引用符を使用します。一重引用符と二重引用符他のルールに従ってください;[1]と[2]もご覧ください。また、正規表現のみが必要です。

@waltinatorが思い出したように、重要な修正ファイルをすべてバックアップしておく必要があります。/etc/設定ファイルはい。牛に似た一種の栄養sed残念ながら、移植性のないバックアップを作成するオプションがあるため、回避策は最初に変更されたファイルのバックアップコピーを作成し、そのバックアップコピーで作業し、-i標準出力を新しいファイルにリダイレクトすることです。

したがって、コマンドは次のようにする必要があります。

su -c 'cp /etc/profile /etc/profile.bak; sed "s,^\\(if \\[ \"\`id -u\`\".*\\)\$,\\#\\1\\
if [[ \"\$(id -u)\" == \"0\" || \"\$(id -un)\" == \"\${HOME##*/}\" ]];\
then," /etc/profile.bak > /etc/profile'

ただし、規制を遵守するにはPOSIXシェン(1p)(また:[3])次のような非POSIX構文を避けるべきです。

if [[ ... == ... || ... == ... ]]; then ...

代わりに、次のものを使用できます。

if [ ... = ... ] || [ ... = ... ]; then ...

このように:

su -c 'cp /etc/profile /etc/profile.bak; sed "s,^\\(if \\[ \"\`id -u\`\".*\\)\$,\\#\\1\\
if [ \"\$(id -u)\" = \"0\" ] || [ \"\$(id -un)\" = \"\${HOME##*/}\" ];\
then," /etc/profile.bak > /etc/profile'

実行を避けることもできます完全に変わった/etc/設定ファイル、ファイルの場合/etc/profile.bakすでに存在しています:

if [ ! -f /etc/profile.bak ]; then
su -c 'cp /etc/profile /etc/profile.bak; sed "s,^\\(if \\[ \"\`id -u\`\".*\\)\$,\\#\\1\\
if [ \"\$(id -u)\" = \"0\" ] || [ \"\$(id -un)\" = \"\${HOME##*/}\" ];\
then," /etc/profile.bak > /etc/profile'
fi

代替(正しい)方法

コメントを見て実際にやりたいことは、利用可能なユーザーアカウントを自動的に作成することです。Sudo(8)/usr/local/sbin:/usr/sbin:/sbinこれは、重要なシステムファイルを変更するPATHことなく簡単に達成できます。/etc/設定ファイル

これを行うには、次の操作を行う必要があります。

  1. ルートとしてログインします。ユーザーを自動的に生成するスクリプト(たとえば、createuserユーザー名を最初のパラメータとして受け入れるnewuser)を生成する場合は、次のパラメータに渡すことができます。Sudoまたは、例えば。su -c 'createuser newuser'
  2. (ここから最後まで、おそらくスクリプトの内部になります)以下を使用して新しいユーザーアカウントを作成します。
useradd -m newuser
  1. newuser追加する/etc/sudoers、従って実行することができますSudoroot権限を取得します。
printf "newuser  ALL=(ALL:ALL) ALL\n" >> /etc/sudoers

スクリプトではこれが少し異なります。ユーザー名を変数に保存した場合user

printf "%s  ALL=(ALL:ALL) ALL\n" "$user" >> /etc/sudoers
  1. /usr/local/sbin:/usr/sbin:/sbin前にPATH付く/home/newuser/.profile環境をカスタマイズしてください。
printf "%s\n" 'export PATH=/usr/local/sbin:/usr/sbin:/sbin${PATH+:}"$PATH"' \
      >>/home/newuser/.profile
  1. 所有権と権限の変更/home/newuser/.profile:
chown newuser:newuser /home/newuser/.profile
chmod 644 /home/newuser/.profile
  1. パスワード設定newuser(パスワードを変更するにはttyが必要です):
passwd newuser

または、次のように設定してください。「期限切れ」、これはユーザーが次回ログインするときに強制的に設定し、ttyを必要としません。

passwd -e newuser

付録

これら2つの要件を組み合わせて設定または脱退したい場合PATH sudoを実行して作成された環境の内部、望むよりsudo$ PATHを保存する方法は?。 Slackware64 15.0では、基本的に上記の「解決方法」の手順に加えて追加の手順は必要ありません。

newuser@darkstar:~$ sudo sh -c 'printf "%s\n" "$PATH"'
/sbin:/usr/sbin:/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/lib64/qt5/bin

引用する

  1. POSIXシェルコマンド言語、(引用符2.2、二重引用符2.2.2、二重引用符2.2.3)
    https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02
  2. Bashマニュアル、3.1.2引用
    https://www.gnu.org/software/bash/manual/html_node/Quoting.html
  3. POSIX シェルコマンド言語
    https://pubs.opengroup.org/onlinepubs/9699919799/idx/shell.html

関連情報