who コマンドの日付と時刻の出力を一貫して表示します。

who コマンドの日付と時刻の出力を一貫して表示します。

他のLinuxサーバーからSSH経由でDebian 12サーバーに接続し、次のコマンドを実行するとWHOコマンドを実行すると、以下が表示されます。

test-user    pts/1        2024-01-24 11:13 (xx.xx.xx.xx)

ただし、Windowsターミナルまたはサードパーティ製のアプリケーションを使用してWindows 11システムで同じユーザーを使用し、実行している同じDebian 12サーバーに接続する場合WHOコマンドを実行すると、日付/時刻形式が異なるように表示されます。

test-user    pts/0        Jan 24 11:15 (xx.xx.xx.xx)

私はこのルートを走っています。/etc/設定ファイルログインするたびにユーザーのIPアドレスを確認しますが、出力が異なり、これらのスペースが結果を変更するため機能しません。

myip=$(who -m | awk '{print substr($5, 2, length($5) - 2)}')

日付/時刻出力を制御する方法はありますか?WHO注文する?この動作の原因は何ですか?

修正する

次に、ロケールコマンドを実行します。

Linuxでは:

$locale

LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=

Windows 11から起動

$locale

LANG=
LANGUAGE=
LC_CTYPE="POSIX"
LC_NUMERIC="POSIX"
LC_TIME="POSIX"
LC_COLLATE="POSIX"
LC_MONETARY="POSIX"
LC_MESSAGES="POSIX"
LC_PAPER="POSIX"
LC_NAME="POSIX"
LC_ADDRESS="POSIX"
LC_TELEPHONE="POSIX"
LC_MEASUREMENT="POSIX"
LC_IDENTIFICATION="POSIX"
LC_ALL=

私が接続したLinuxサーバーではこれが起こらないようです。これは異なり、以下の解決策で説明されています。

以下の説明に基づいて根本的な原因を理解したときに、これらの提案を使用することを決定し、すべて私のユースケースに適していました。

答え1

見たらGNU実装のためのソースコードwho、望むより:

  if (hard_locale (LC_TIME))
    {
      time_format = "%Y-%m-%d %H:%M";
      time_format_width = 4 + 1 + 2 + 1 + 2 + 1 + 2 + 1 + 2;
    }
  else
    {
      time_format = "%b %e %H:%M";
      time_format_width = 3 + 1 + 2 + 1 + 2 + 1 + 2;
    }

これhard_locale()gnulib宣言次のように説明してください。

 /* Return true if the specified CATEGORY of the current locale is hard, i.e.
   different from the C or POSIX locale that has a fixed behavior.
   CATEGORY must be one of the LC_* values, but not LC_ALL.  */
 extern bool hard_locale (int category);

だから、

  • C/POSIX ロケールでは、次のようになります。<EnglishMonthNameAbbreviation> <SpacePaddedDayOfTheMonth> <ZeroPaddedHour>:<ZeroPaddedMinute>
  • その他のロケール:標準ISO8601スタイルYYYY-MM-DD HH:MM日付。

LC_TIMEカテゴリのロケールはenv変数によって決定されますLC_ALL。この変数が設定されていない場合、または両方が設定されていない場合は、この変数が決定されますLC_TIME。あるいは、システムにインストールされたロケールの文字列がない場合、または3つの変数がすべて設定されていない場合は、C / POSIXロケールが取得されます。LC_ALLLANGCPOSIX

このコマンドはサーバーに変数を渡すことができ、多くのUnixシリーズシステムではデフォルトでそれを行いますssh。また、多くのUnixシリーズシステムでは、次のように構成されています。LANGLC_*sshd受け入れるデフォルトでは、これらの変数LANGLC_*変数があります。しかし、Microsoft WindowsはUnixのようなシステムではありません。使用しているクライアントがこれらの変数を渡しても、sshサーバーでサポートされているロケール名を含む一部の変数が環境に存在する可能性はほとんどありませんLANGLC_*

これはCWindowsでingするとき-like日付形式を得るsshが、他のUnix系システムでsshingするときはISO8601スタイルの日付形式を得る理由を説明します。

一貫した形式を取得するには、C次を実行してロケールを強制的に適用できますwho

LC_ALL=C who -m

()ただし、ここでは、ttyログイン位置情報を含む行の最初の項目と最後の項目の間の部分を抽出したいと思います。次のようにできます。

who -m | perl -ne 'print $1 if /\((.*)\)/'

ttyによって生成され、これらの環境変数が(またはによってsshd)消去されていないと仮定する場合は、次のようにして変数からSSHクライアントのIPアドレスを抽出できます。sudosu -SSH_CLIENT

ipaddress="${SSH_CLIENT%% *}"

答え2

上記の提案を使用して問題を解決しました。

myip=$(echo $SSH_CONNECTION | awk '{print $1}')

2番目のアプローチも効果があるようです。

myip=$(echo $SSH_CLIENT | awk '{print $1}')

みんなありがとうございます!

関連情報