2017-11-01 2 views
0

\hは、ホスト名に展開されるbashプロンプトのエスケープシーケンスです。どこからホスト名を取得しますか?私のシステムでは、hostname -fまたは/etc/hostsまたは/etc/hostnameまたは/etc/sysconfig/networkまたはではなく、どこでも見つけることができない値が表示されます。だから私はそれがどこから来ているのだろうかと思っています。私のシステムはCentos 7.4です。私は、UUIDのようなものが格納されている隠された場所があることを知っています。過去に同様の隠されたホスト名のタイプの問題に遭遇したことを思い出していますが、詳細を覚えていません。bashプロンプトのエスケープシーケンスはどこですか hホスト名を取得しますか?

+0

この質問はStack Exchangeネットワークの[Unix&Linux](http://unix.stackexchange.com/tour)に属しているため、この質問を議論の対象外としています。 – Cyrus

+0

'bash'はUnix以外のシステムでも実行できます。ここで' \ h'エスケープのセマンティクスについて質問するのが妥当です。 – chepner

+0

それで、systemdには、ハードドライブからのホスト名の保存とアクセスを含む独自の 'hostnamectl'というものがあります。 –

答えて

5

bash source codeを見ると、に、gethostname(2)という、カーネルからホスト名を取得するPOSIXシステムコールが呼び出されます。

/* It's highly unlikely that this will change. */ 
if (current_host_name == 0) 
    { 
    /* Initialize current_host_name. */ 
    if (gethostname (hostname, 255) < 0) 
     current_host_name = "??host??"; 
    else 
     current_host_name = savestring (hostname); 
    } 

これは必ずしも正式な文字列ではありません。カーネルはマシンのネットワークホスト名を実際には知りません。 sethostname(2)に渡されたものを報告します。 uname(2) man pageから引用すると:

一方、[ホスト名]は無意味である:それはいくつかの未定義のネットワークでは、本機の名前を与えますが、通常はマシンが複数のネットワークであり、複数の名前を持ちます。さらに、カーネルはそのようなことを知る方法がないので、ここで何を答えなければならないのかを伝える必要があります。

gethostname(2)のないLinux以外のシステムでは、bashはuname(2)に戻ります。 uname(2)が利用できない場合、単に "unknown"と表示されます。あなたはlib/sh/oslib.cでそのロジックを見ることができます:ホスト名が変更された場合

#if !defined (HAVE_GETHOSTNAME) 
# if defined (HAVE_UNAME) 
# include <sys/utsname.h> 
int 
gethostname (name, namelen) 
    char *name; 
    int namelen; 
{ 
    int i; 
    struct utsname ut; 

    --namelen; 

    uname (&ut); 
    i = strlen (ut.nodename) + 1; 
    strncpy (name, ut.nodename, i < namelen ? i : namelen); 
    name[namelen] = '\0'; 
    return (0); 
} 
# else /* !HAVE_UNAME */ 
int 
gethostname (name, namelen) 
    char *name; 
    int namelen; 
{ 
    strncpy (name, "unknown", namelen); 
    name[namelen] = '\0'; 
    return 0; 
} 
# endif /* !HAVE_UNAME */ 
#endif /* !HAVE_GETHOSTNAME */ 

\hは更新されません。この値は、シェルの初期化時に起動時にキャッシュされます。

[[email protected]]$ hostname 
malkovich 
[[email protected]]$ sudo hostname kaufman 
[[email protected]]$ hostname 
kaufman 
[[email protected]]$ bash 
[[email protected]] 
1

(お使いのLinuxディストリビューションのほとんどのパッケージがそうであるように)それはおそらく(ちょうど推測)gethostname(2)システムコール使用しています(すべてのsyscalls(2)がそうであるように、カーネルによって処理され、...)

ところで、GNU bashがありますfree software;したがって、のソースをダウンロードしてくださいcodestudy it;use the source, Luke!およびopen the source moreでお願いします。

さらに興味深いのは、その情報がbashによってキャッシュされる方法です。すべてのコマンドでgethostnameが呼び出されますか?また、strace(1)を使用して調べることもできます。


はもちろん、フリーソフトウェアのソースコードあなたが興味があるたびに勉強の習慣を取ります。 stracegdbデバッガを使用して、動的な動作を理解してください。

フランスの歌手、G.Bedosは、私たちに語った "ラリベルテNE s'use queのSIのNE s'enのSERTのPAS上"、つまり

あなたがそれを使用しない場合は自由が磨耗します

フリーソフトウェアのソースコードに


ので、次回、してくださいダイビング(翻訳は私がフランス語ではなく英語のネイティブスピーカーです、私のものです)。 あなたの自由を練習することが重要です、それは何ですかfree software is aboutです。

関連する問題