他の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_ALL
LANG
C
POSIX
このコマンドはサーバーに変数を渡すことができ、多くのUnixシリーズシステムではデフォルトでそれを行いますssh
。また、多くのUnixシリーズシステムでは、次のように構成されています。LANG
LC_*
sshd
受け入れるデフォルトでは、これらの変数LANG
とLC_*
変数があります。しかし、Microsoft WindowsはUnixのようなシステムではありません。使用しているクライアントがこれらの変数を渡しても、ssh
サーバーでサポートされているロケール名を含む一部の変数が環境に存在する可能性はほとんどありませんLANG
。LC_*
これはC
Windowsで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アドレスを抽出できます。sudo
su -
SSH_CLIENT
ipaddress="${SSH_CLIENT%% *}"
答え2
上記の提案を使用して問題を解決しました。
myip=$(echo $SSH_CONNECTION | awk '{print $1}')
2番目のアプローチも効果があるようです。
myip=$(echo $SSH_CLIENT | awk '{print $1}')
みんなありがとうございます!