জাভাতে বর্তমান কম্পিউটারের হোস্টনেম পাওয়ার জন্য নিচের কোনটি সর্বোত্তম এবং বহনযোগ্য উপায়?
Runtime.getRuntime().exec("hostname")
বনাম
InetAddress.getLocalHost().getHostName()
জাভাতে বর্তমান কম্পিউটারের হোস্টনেম পাওয়ার জন্য নিচের কোনটি সর্বোত্তম এবং বহনযোগ্য উপায়?
Runtime.getRuntime().exec("hostname")
বনাম
InetAddress.getLocalHost().getHostName()
উত্তর:
কঠোরভাবে বলতে - আপনার কাছে hostname(1)
ইউনিক্সে ফোন করা বা বলা ছাড়া কোনও বিকল্প নেই gethostname(2)
। এটি আপনার কম্পিউটারের নাম। এই জাতীয় আইপি ঠিকানার মাধ্যমে হোস্টনাম নির্ধারণের জন্য কোনও প্রচেষ্টা
InetAddress.getLocalHost().getHostName()
কিছু পরিস্থিতিতে ব্যর্থ হতে বাধ্য:
হোস্টের নাম (হোস্টনাম) দিয়ে কোনও আইপি-ঠিকানা নাম গুলিয়ে ফেলবেন না। একটি রূপক এটি আরও পরিষ্কার করে তুলতে পারে:
"লন্ডন" নামে একটি বৃহত শহর (সার্ভার) রয়েছে। শহরের দেয়াল ভিতরে অনেক ব্যবসা ঘটে। শহরে কয়েকটি গেট (আইপি ঠিকানা) রয়েছে addresses প্রতিটি গেটের একটি নাম ("উত্তর গেট", "রিভার গেট", "সাউদাম্পটন গেট" ...) রয়েছে তবে ফটকটির নামটি শহরের নাম নয়। এছাড়াও আপনি কোনও গেটের নাম ব্যবহার করে শহরের নামটি কমাতে পারবেন না - "উত্তর গেট" কেবলমাত্র একটি শহর নয়, আরও বড় শহরগুলির অর্ধেক ধরে ফেলবে। তবে - একজন অপরিচিত (আইপি প্যাকেট) নদীর তীরে চলে এবং একজন স্থানীয়কে জিজ্ঞাসা করে: "আমার একটি অদ্ভুত ঠিকানা রয়েছে: 'রিভারগেট, দ্বিতীয় বাম, তৃতীয় বাড়ি' you আপনি আমাকে সাহায্য করতে পারেন?" স্থানীয় বলেছেন: "অবশ্যই আপনি সঠিক রাস্তায় রয়েছেন, কেবল এগিয়ে যান এবং আপনি অর্ধ ঘন্টার মধ্যে আপনার গন্তব্যে পৌঁছে যাবেন।"
এটি আমার মনে হয় এটি বেশ চিত্রিত করে।
সুসংবাদটি হ'ল: আসল হোস্টনাম সাধারণত প্রয়োজন হয় না। বেশিরভাগ ক্ষেত্রে এই হোস্টের কোনও আইপি ঠিকানার সমাধান করা নামই করবে। (অচেনা লোকটি নর্থগেট দিয়ে শহরে প্রবেশ করতে পারে তবে সহায়ক স্থানীয় লোকেরা "২ য় বাম" অংশটি অনুবাদ করে))
তাহলে অবশিষ্ট কোণ ক্ষেত্রে আপনি ব্যবহার করা আবশ্যক নির্ধারক সি ফাংশন যা - এই কনফিগারেশন সেটিং-এর উৎস gethostname(2)
। যে ফাংশন প্রোগ্রাম দ্বারা বলা হয় hostname
।
InetAddress.getLocalHost().getHostName()
আরও বহনযোগ্য উপায়।
exec("hostname")
hostname
কমান্ডটি কার্যকর করতে অপারেটিং সিস্টেমকে ডেকে আনে ।
এসও-তে আরও কয়েকটি সম্পর্কিত সম্পর্কিত উত্তর এখানে দেওয়া হয়েছে:
সম্পাদনা: আপনার পরিস্থিতির উপর নির্ভর করে কেন এটি প্রত্যাশার মতো কাজ করতে পারে না তার বিশদ জানতে আপনাকে এএইচ এর উত্তর বা আর্নোট এঙ্গেলেনের জবাব একবার দেখে নেওয়া উচিত । এই ব্যক্তি যিনি বিশেষভাবে পোর্টেবলের জন্য অনুরোধ করেছিলেন তার উত্তর হিসাবে, আমি এখনও মনে করি getHostName()
ঠিক আছে, তবে তারা কিছু ভাল পয়েন্ট তুলে ধরেছে যা বিবেচনা করা উচিত।
InetAddress.getLocalHost()
কিছু ক্ষেত্রে লুপব্যাক ডিভাইস ফেরত দেয়। getHostName()
সেক্ষেত্রে , "লোকালহোস্ট" প্রদান করে, যা খুব কার্যকর নয়।
অন্যরা যেমন উল্লেখ করেছে, ডিএনএস রেজোলিউশনের ভিত্তিতে হোস্টনাম পাওয়া অবিশ্বাস্য।
যেহেতু এই প্রশ্নটি দুর্ভাগ্যক্রমে 2018 এ এখনও প্রাসঙ্গিক , তাই আমি আমার সিস্টেম-স্বাধীন সমাধানটি বিভিন্ন সিস্টেমে কিছু পরীক্ষা চালিয়ে আপনার সাথে ভাগ করে নিতে চাই।
নিম্নলিখিত কোডটি নিম্নলিখিতটি করার চেষ্টা করে:
উইন্ডোজ এ
COMPUTERNAME
পরিবেশের পরিবর্তনশীল মাধ্যমে পড়ুন System.getenv()
।
কার্যকর করুন hostname.exe
এবং প্রতিক্রিয়া পড়ুন
লিনাক্সে
HOSTNAME
পরিবেশের পরিবর্তনশীল মাধ্যমে পড়ুনSystem.getenv()
কার্যকর করুন hostname
এবং প্রতিক্রিয়া পড়ুন
পড়ুন /etc/hostname
(এটি করার জন্য আমি সম্পাদন করছি cat
যেহেতু স্নিপেটে ইতিমধ্যে কার্যকর করার এবং পড়ার কোড রয়েছে Simp কেবল ফাইলটি পড়া ভাল হবে, তবে)।
কোড:
public static void main(String[] args) throws IOException {
String os = System.getProperty("os.name").toLowerCase();
if (os.contains("win")) {
System.out.println("Windows computer name through env:\"" + System.getenv("COMPUTERNAME") + "\"");
System.out.println("Windows computer name through exec:\"" + execReadToString("hostname") + "\"");
} else if (os.contains("nix") || os.contains("nux") || os.contains("mac os x")) {
System.out.println("Unix-like computer name through env:\"" + System.getenv("HOSTNAME") + "\"");
System.out.println("Unix-like computer name through exec:\"" + execReadToString("hostname") + "\"");
System.out.println("Unix-like computer name through /etc/hostname:\"" + execReadToString("cat /etc/hostname") + "\"");
}
}
public static String execReadToString(String execCommand) throws IOException {
try (Scanner s = new Scanner(Runtime.getRuntime().exec(execCommand).getInputStream()).useDelimiter("\\A")) {
return s.hasNext() ? s.next() : "";
}
}
বিভিন্ন অপারেটিং সিস্টেমের জন্য ফলাফল:
ম্যাকোস 10.13.2
Unix-like computer name through env:"null"
Unix-like computer name through exec:"machinename
"
Unix-like computer name through /etc/hostname:""
ওপেনসুস 13.1
Unix-like computer name through env:"machinename"
Unix-like computer name through exec:"machinename
"
Unix-like computer name through /etc/hostname:""
উবুন্টু 14.04 এলটিএসecho $HOSTNAME
সঠিক হোস্টনামটি ফেরত দেওয়ার
পরে এটি এক বিস্ময়কর , তবে System.getenv("HOSTNAME")
তা নয়:
Unix-like computer name through env:"null"
Unix-like computer name through exec:"machinename
"
Unix-like computer name through /etc/hostname:"machinename
"
সম্পাদনা: লেগোলা 1010 অনুসারে , System.getenv("HOSTNAME")
আপনি export HOSTNAME
জাভা কোডটি কার্যকর করার আগে চালালে উবুন্টু 14.04 এ কাজ করে ।
উইন্ডোজ 7
Windows computer name through env:"MACHINENAME"
Windows computer name through exec:"machinename
"
উইন্ডোজ 10
Windows computer name through env:"MACHINENAME"
Windows computer name through exec:"machinename
"
মেশিনের নামগুলি প্রতিস্থাপন করা হয়েছে তবে আমি মূলধন এবং কাঠামো রেখেছি। এক্সিকিউট করার সময় অতিরিক্ত নিউলাইনটি নোট করুন hostname
, আপনাকে কিছু ক্ষেত্রে এটি অ্যাকাউন্টে নিতে হতে পারে।
export HOSTNAME
উবুন্টু 14.04 এলটিএসে জাভা কোড চালানোর আগে এটি দ্বারা ফিরে আসে System.getenv("HOSTNAME")
।
export HOSTNAME
জাভা ব্যবহার করার জন্য আপনার স্পষ্টভাবে বলতে হবে? আমি ভেবেছিলাম এটি PATH এর মতো একটি ডিফল্ট এনভিরভ ভার হওয়া উচিত।
\A
বিভেদক শুধু একটি ব্যবহার সমগ্র InputStream পড়ার জন্য একটি হ্যাক হয় Scanner
।
InetAddress.getLocalHost().getHostName()
আরও ভাল (নিক দ্বারা ব্যাখ্যা হিসাবে), কিন্তু এখনও খুব ভাল না
একটি হোস্ট বিভিন্ন বিভিন্ন হোস্টনামের অধীনে পরিচিত হতে পারে। সাধারণত আপনি একটি নির্দিষ্ট প্রসঙ্গে আপনার হোস্টের হোস্টের নামটি সন্ধান করবেন।
উদাহরণস্বরূপ, একটি ওয়েব অ্যাপ্লিকেশনটিতে, আপনি বর্তমানে যে হ্যান্ডেলটির অনুরোধটি জারি করেছেন তার দ্বারা ব্যবহৃত হোস্টনামের সন্ধান করতে পারেন। আপনি কীভাবে আপনার ওয়েব অ্যাপ্লিকেশনটির জন্য কোন কাঠামো ব্যবহার করছেন তার উপর নির্ভর করে কীভাবে এটি সন্ধান করতে পারেন।
অন্য কোনও ইন্টারনেট-মুখোমুখি পরিষেবাতে, আপনি চাইবেন যে হোস্টনামটি আপনার পরিষেবাটি 'বাহির' থেকে পাওয়া যায়। প্রক্সি, ফায়ারওয়ালস ইত্যাদির কারণে এটি এমনকি আপনার পরিষেবাটি যে মেশিনে ইনস্টল করা আছে তার কোনও হোস্টনামও নাও থাকতে পারে - আপনি যুক্তিসঙ্গত ডিফল্ট নিয়ে আসতে চেষ্টা করতে পারেন, তবে যিনি এটি ইনস্টল করেন অবশ্যই আপনার এই কনফিগারযোগ্য করা উচিত।
যদিও এই বিষয়টি ইতিমধ্যে উত্তর দেওয়া হয়েছে আরও বলার অপেক্ষা রাখে না।
প্রথমত: স্পষ্টতই আমাদের এখানে কিছু সংজ্ঞা দরকার। InetAddress.getLocalHost().getHostName()
হোস্ট নাম দেয় যেমন একটি নেটওয়ার্ক দৃষ্টিকোণ থেকে দেখা । এই পদ্ধতির সমস্যাগুলি অন্যান্য উত্তরে ডকুমেন্টেড রয়েছে: এটির জন্য প্রায়শই একটি ডিএনএস অনুসন্ধান প্রয়োজন হয়, হোস্টের একাধিক নেটওয়ার্ক ইন্টারফেস রয়েছে এবং এটি কখনও কখনও সরলভাবে ব্যর্থ হয় (নীচে দেখুন)।
তবে যে কোনও ওএসে আরও একটি নাম রয়েছে। হোস্টের একটি নাম যা বুট প্রক্রিয়াতে নেটওয়ার্ক শুরু হওয়ার অনেক আগেই সংজ্ঞায়িত হয়ে যায়। উইন্ডোজ হিসাবে এই বোঝায় computername , লিনাক্স আহ্বান এটা হোস্টনাম কার্নেল এবং সোলারিস শব্দ ব্যবহার nodename । আমি কম্পুটারনেম শব্দটি সবচেয়ে পছন্দ করি , তাই এখন থেকে আমি এই শব্দটি ব্যবহার করব।
লিনাক্স / ইউনিক্স উপর computername কি সি ফাংশন থেকে পেতে হয় gethostname()
, অথবা hostname
শেল বা থেকে কমান্ড HOSTNAME
মধ্যে শাঁস ব্যাশ মত এনভায়রনমেন্ট ভেরিয়েবল।
উইন্ডোজে কমপিউটারনামটি আপনি পরিবেশ পরিবর্তনশীল COMPUTERNAME
বা উইন 32 GetComputerName
ফাংশন থেকে পান।
জাভাটির কাছে আমি 'সংবিধান' হিসাবে সংজ্ঞায়িত করেছি তা পাওয়ার কোনও উপায় নেই। অবশ্যই, উইন্ডোজ কলিংয়ের মতো অন্যান্য উত্তরে বর্ণিত ওয়ার্কআরউন্ডস রয়েছে System.getenv("COMPUTERNAME")
, তবে ইউনিক্স / লিনাক্সে জেএনআই / জেএনএ বা অবলম্বন না করে কোনও ভাল কর্মক্ষেত্র নেই Runtime.exec()
। আপনি যদি কোনও জেএনআই / জেএনএ সমাধানটিকে আপত্তি করেন না, তবে গেথস্টনাম ৪ জে রয়েছে যা মৃত সহজ এবং ব্যবহারে খুব সহজ।
আসুন দুটি উদাহরণ সহ এগিয়ে চলুন, একটি লিনাক্স থেকে এবং একটি সোলারিস থেকে, যা প্রমাণ করে যে আপনি কীভাবে সহজেই এমন পরিস্থিতিতে পড়তে পারেন যেখানে আপনি স্ট্যান্ডার্ড জাভা পদ্ধতি ব্যবহার করে সামঞ্জস্য পেতে পারেন না।
একটি নতুন নির্মিত সিস্টেমে, যেখানে ইনস্টলেশন চলাকালীন হোস্টটির নাম 'চিকাগো' রাখা হয়েছে, আমরা এখন তথাকথিত কার্নেল হোস্ট-নেম পরিবর্তন করি:
$ hostnamectl --static set-hostname dallas
এখন কার্নেলের হোস্ট-নেমটি 'ডালাস', যেমন হোস্টনেম কমান্ড থেকে স্পষ্ট:
$ hostname
dallas
কিন্তু আমাদের এখনও আছে
$ cat /etc/hosts
127.0.0.1 localhost
127.0.0.1 chicago
এটিতে কোনও ভুল কনফিগারেশন নেই। এর অর্থ কেবল হোস্টের নেটওয়ার্ককৃত নাম (বা বরং লুপব্যাক ইন্টারফেসের নাম) হোস্টের সামঞ্জস্য থেকে আলাদা।
এখন, কার্যকর করার চেষ্টা করুন InetAddress.getLocalHost().getHostName()
এবং এটি java.net নিক্ষেপ করবে nঅজানাহোস্টএক্সেপশন। আপনি মূলত আটকে আছেন মান 'ডালাস' বা মান 'চিকাগো' না উদ্ধারের কোনও উপায় নেই।
নীচের উদাহরণটি সোলারিস 11.3 এর উপর ভিত্তি করে।
হোস্টটি ইচ্ছাকৃতভাবে কনফিগার করা হয়েছে যাতে লুপব্যাকের নাম <> নোডনাম।
অন্য কথায় আমাদের রয়েছে:
$ svccfg -s system/identity:node listprop config
...
...
config/loopback astring chicago
config/nodename astring dallas
এবং / ইত্যাদি / হোস্টের সামগ্রী:
:1 chicago localhost
127.0.0.1 chicago localhost loghost
এবং হোস্টনেম কমান্ডের ফলাফলটি হ'ল:
$ hostname
dallas
ঠিক যেমন লিনাক্স উদাহরণে একটি কল InetAddress.getLocalHost().getHostName()
ব্যর্থ হবে
java.net.UnknownHostException: dallas: dallas: node name or service name not known
লিনাক্সের উদাহরণের মতো আপনি এখন আটকে আছেন। মান 'ডালাস' বা মান 'চিকাগো' না উদ্ধারের কোনও উপায় নেই।
খুব প্রায়শই আপনি দেখতে পাবেন যে InetAddress.getLocalHost().getHostName()
প্রকৃতপক্ষে একটি মান প্রদান করবে যা সংখ্যার সমান। সুতরাং কোনও সমস্যা নেই (নাম রেজ্যুলেশনের অতিরিক্ত ওভারহেড ব্যতীত)।
সমস্যাটি PaaS এনভায়রনমেন্টের মধ্যে দেখা দেয় যেখানে কম্পিউটার এবং লুপব্যাক ইন্টারফেসের নামের মধ্যে পার্থক্য রয়েছে। উদাহরণস্বরূপ লোকেরা আমাজন ইসি 2 তে সমস্যাগুলি প্রতিবেদন করে।
কিছুটা অনুসন্ধান এই আরএফই রিপোর্টটি প্রকাশ করে: লিঙ্ক 1 , লিঙ্ক 2 । তবে, এই প্রতিবেদনের মন্তব্যগুলি বিচার করে মনে হচ্ছে জেডিকে দলটি মূলত ভুল বোঝাবুঝি করেছে, সুতরাং এটির সমাধানের সম্ভাবনা কম।
আমি আরএফইতে অন্যান্য প্রোগ্রামিং ভাষার সাথে তুলনা পছন্দ করি।
COMPUTERNAME
উইন্ডোজে, HOSTNAME
বেশিরভাগ আধুনিক ইউনিক্স / লিনাক্স শেলগুলিতে - পরিবেশের ভেরিয়েবলগুলি একটি দরকারী উপায় সরবরাহ করতে পারে ।
দেখা: https://stackoverflow.com/a/17956000/768795
আমি এগুলিকে "পরিপূরক" পদ্ধতি হিসাবে ব্যবহার করছি InetAddress.getLocalHost().getHostName()
, যেহেতু বেশিরভাগ লোক দেখায়, এই ফাংশনটি সমস্ত পরিবেশে কাজ করে না।
Runtime.getRuntime().exec("hostname")
অন্য সম্ভাব্য পরিপূরক। এই পর্যায়ে, আমি এটি ব্যবহার করি নি।
import java.net.InetAddress;
import java.net.UnknownHostException;
// try InetAddress.LocalHost first;
// NOTE -- InetAddress.getLocalHost().getHostName() will not work in certain environments.
try {
String result = InetAddress.getLocalHost().getHostName();
if (StringUtils.isNotEmpty( result))
return result;
} catch (UnknownHostException e) {
// failed; try alternate means.
}
// try environment properties.
//
String host = System.getenv("COMPUTERNAME");
if (host != null)
return host;
host = System.getenv("HOSTNAME");
if (host != null)
return host;
// undetermined.
return null;
StringUtils
তবে এটি অ্যাপাচি কমন্স-ল্যাং প্রকল্প সরবরাহ করেছে। এটি ব্যবহার করা বা এটির মতো কিছু ব্যবহারের জন্য সুপারিশ করা হয়।
System.getenv("HOSTNAME")
আউট জাভা জন্য বিনশেল মাধ্যমে ম্যাক নাল এসেছিলেন, কিন্তু PATH
ঠিক নিষ্কাশিত। আমি echo $HOSTNAME
ম্যাকের উপরও এটি করতে পারি , কেবল সিস্টেম.জটেনভ ("HOSTNAME") এর সমস্যা আছে বলে মনে হচ্ছে। স্ট্রেঞ্জ।
জাভাতে বর্তমান কম্পিউটারের হোস্টনেম পাওয়ার সর্বাধিক বহনযোগ্য উপায় হ'ল:
import java.net.InetAddress;
import java.net.UnknownHostException;
public class getHostName {
public static void main(String[] args) throws UnknownHostException {
InetAddress iAddress = InetAddress.getLocalHost();
String hostName = iAddress.getHostName();
//To get the Canonical host name
String canonicalHostName = iAddress.getCanonicalHostName();
System.out.println("HostName:" + hostName);
System.out.println("Canonical Host Name:" + canonicalHostName);
}
}
আপনি যদি মেন সেন্ট্রাল থেকে বাহ্যিক নির্ভরতা ব্যবহারের বিরুদ্ধে নন তবে আমি নিজের জন্য এই সমস্যাটি সমাধান করার জন্য গেথস্টনাম ৪ জে লিখেছি। এটি কেবল লিবিসি-র গেথোস্টনাম ফাংশন (বা উইন্ডোজে কম্পিউটারনাম পায়) কল করতে জেএনএ ব্যবহার করে এবং এটি আপনাকে স্ট্রিং হিসাবে ফিরিয়ে দেয়।
hostName == null;
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
{
while (interfaces.hasMoreElements()) {
NetworkInterface nic = interfaces.nextElement();
Enumeration<InetAddress> addresses = nic.getInetAddresses();
while (hostName == null && addresses.hasMoreElements()) {
InetAddress address = addresses.nextElement();
if (!address.isLoopbackAddress()) {
hostName = address.getHostName();
}
}
}
}
কেবল একটি লাইনার ... ক্রস প্ল্যাটফর্ম (উইন্ডোজ-লিনাক্স-ইউনিক্স-ম্যাক (ইউনিক্স)) [সর্বদা কাজ করে, কোনও ডিএনএস প্রয়োজন হয় না]:
String hostname = new BufferedReader(
new InputStreamReader(Runtime.getRuntime().exec("hostname").getInputStream()))
.readLine();
তুমি করেছ !!
InetAddress.getLocalHost ()। GetHostName () হ'ল দু'জনের মধ্যে সেরা উপায় কারণ এটি বিকাশকারী স্তরের সেরা বিমূর্ততা।