"আরগভি [0] = নাম-এক্সিকিউটেবল" একটি গ্রহণযোগ্য মান বা কেবল একটি সাধারণ সম্মেলন?


104

main()কোনও সি বা সি ++ অ্যাপ্লিকেশনে আর্গুমেন্ট পাস করার সময় , argv[0]সর্বদা মৃত্যুদন্ড কার্যকর করার নাম থাকবে? বা এটি কি কেবল একটি সাধারণ সম্মেলন এবং সময়টির 100% সত্য হওয়ার নিশ্চয়তা নেই?


20
ইউনিক্স তারিখে, বিবেচনা করুন: execl("/home/hacker/.hidden/malicious", "/bin/ls", "-s", (char *)0);। এক্সিকিউটেবলের নামের মানটির সাথে কোনও সম্পর্ক নেই argv[0]
জোনাথন লেফলার

উত্তর:


122

অনুমান করা (এমনকি শিক্ষিত অনুমানক) মজাদার তবে নিশ্চিত হওয়ার জন্য আপনার অবশ্যই স্ট্যান্ডার্ড ডকুমেন্টগুলিতে যেতে হবে। উদাহরণস্বরূপ, আইএসও সি 11 বলেছেন (আমার জোর):

মানটি যদি argcশূন্যের চেয়ে বেশি হয় তবে নির্দেশিত স্ট্রিং প্রোগ্রামটির নাম argv[0] উপস্থাপন করে; argv[0][0]হোস্ট পরিবেশ থেকে প্রোগ্রামের নামটি উপলব্ধ না হলে নাল অক্ষর হবে shall

সুতরাং না, এটির নামটি উপলব্ধ থাকলে এটি কেবল প্রোগ্রামের নাম এবং এটা "প্রতিনিধিত্ব করে" প্রোগ্রাম নাম, কোনো অগত্যা হয় প্রোগ্রাম নাম। তার আগের বিভাগটি বলে:

মানটি যদি argcশূন্যের চেয়ে বেশি argv[0]হয় তবে argv[argc-1]অন্তর্ভুক্তির মাধ্যমে অ্যারে সদস্যগুলিতে স্ট্রিংয়ের পয়েন্টার থাকতে হবে, যা প্রোগ্রাম শুরু হওয়ার আগে হোস্ট পরিবেশ দ্বারা বাস্তবায়ন-সংজ্ঞায়িত মান দেওয়া হয়।

এটি পূর্ববর্তী মান, সি 99 থেকে অপরিবর্তিত এবং এর অর্থ এটি এমনকি মানগুলি মান দ্বারা নির্ধারিত হয় না - এটি সম্পূর্ণরূপে বাস্তবায়নের উপর নির্ভর করে।

এই উপায়ে প্রোগ্রাম নাম যদি হোস্ট পরিবেশ খালি হতে পারে না এটি প্রদান, এবং অন্য কিছু যদি হোস্ট পরিবেশ নেই প্রদান করা যে, "অন্য কিছু" একরকম প্রোগ্রাম নাম প্রতিনিধিত্ব করে, এটা প্রদান। আমার আরও দুঃখজনক মুহুর্তগুলিতে, আমি এটি সোয়াহিলি ভাষায় অনুবাদ করার বিষয়টি বিবেচনা করব এবং এটি একটি বিকল্প সাইফারের মাধ্যমে চালিয়ে তারপরে বিপরীত বাইট ক্রমে সংরক্ষণ করব :-)।

যাইহোক, বাস্তবায়ন-সংজ্ঞায়িত করে বাস্তবায়ন আবশ্যক ডকুমেন্ট কিভাবে এটি কাজ করে - আইএসও মান একটি নির্দিষ্ট অর্থ আছে। এমনকি ইউনিক্স, যা কলগুলির পরিবারের argv[0]সাথে এটি পছন্দ করে এমন কোনও জিনিস রাখতে execপারে, এটি এটিকে নথিভুক্ত করতে (এবং করবে) করতে হবে।


4
এটি স্ট্যান্ডার্ড হতে পারে তবে ইউনিক্স কেবল এটি প্রয়োগ করে না এবং আপনি এটির উপর নির্ভর করতে পারবেন না।
ডিএমকেকে --- প্রাক্তন-মডারেটর বিড়ালছানা

4
প্রশ্ন ইউনিক্স উল্লেখ না এ সব । এটি একটি সি প্রশ্ন ছিল সহজ এবং সরল, সুতরাং আইএসও সি হ'ল রেফারেন্সের দলিল। প্রোগ্রামটির নামটি বাস্তবায়নের মান হিসাবে সংজ্ঞায়িত করা হয় সুতরাং বাস্তবায়ন যা চায় তা করতে মুক্ত হয়, সেখানে এমন কিছুকে আসল নাম নয় যা অনুমতি দেওয়ার সাথে অন্তর্ভুক্ত করে - আমি ভেবেছিলাম যে আমি পেনাল্টিমেট বাক্যে এটিকে পরিষ্কার করে দিয়েছি।
paxdiablo

4
প্যাক্স, আমি তোমাকে নিচে ভোট দেননি, এবং যারা করেনি কারণ এই উত্তর হিসাবে প্রামাণিক হিসাবে এটি অনুমোদন না করতে পেতে। তবে আমি মনে করি যে এর অবিশ্বাস্যতা argv[0]বাস্তব বিশ্বের প্রোগ্রামিংয়ের জন্য অ্যাপ্রোপোস os
dmckee --- প্রাক্তন-মডারেটর বিড়ালছানা

4
@ ক্যাফ, এটি সঠিক। আমি এটিকে প্রোগ্রামের সম্পূর্ণ পথ ('/ প্রগথ / অগ্র') হিসাবে কেবলমাত্র ফাইলের নাম ('প্রগ'), কিছুটা পরিবর্তিত নাম ('-প্রোগ'), বর্ণনামূলক নাম (' অগ্রগতি ') এবং কিছুই (' ') উন্নয়নের জন্য একটি প্রোগ্রাম। বাস্তবায়নটির কাছে এটি কী ধারণ করে তা নির্ধারণ করতে হয় তবে এটি সমস্ত স্ট্যান্ডার্ডের প্রয়োজন।
প্যাক্সিডিয়াবলো

4
ধন্যবাদ সবাইকে! একটি (আপাতদৃষ্টিতে) সাধারণ প্রশ্ন থেকে দুর্দান্ত আলোচনা। যদিও রিচার্ডের উত্তর * নিক্স অপারেটিং সিস্টেমের জন্য বৈধ, তবে আমি প্যাক্সিডিয়াবলোর উত্তরটি বেছে নিয়েছি কারণ আমি একটি নির্দিষ্ট ওএসের আচরণে কম আগ্রহী এবং মূলত স্বীকৃত মানটির অস্তিত্ব (বা অনুপস্থিত) সম্পর্কে আগ্রহী। (আপনি যদি কৌতূহলী হন তবে মূল প্রশ্নের প্রসঙ্গে - আমার কোনও অপারেটিং সিস্টেম নেই I'm আরগভির সাথে [0])। দুর্দান্ত হওয়ার জন্য স্ট্যাকওভারফ্লোতে +1 করুন!
মাইক Willekes

51

কল *nixসহ টাইপ সিস্টেমের অধীনে exec*(), argv[0]কলারের মধ্যে স্পটটিতে যা কিছু argv0স্থাপন করা হবেexec*() কল।

শেলটি কনভেনশনটি ব্যবহার করে যে এটি প্রোগ্রামের নাম এবং অন্যান্য বেশিরভাগ প্রোগ্রাম একই কনভেনশন অনুসরণ করে argv[0] সাধারণত প্রোগ্রামটির নাম।

তবে একটি দুর্বৃত্ত ইউনিক্স প্রোগ্রাম কল করতে exec()এবং argv[0]এটির পছন্দমতো যে কোনও কিছু তৈরি করতে পারে, তাই সি স্ট্যান্ডার্ড যাই বলুক না কেন, আপনি এই 100% সময়ের উপর নির্ভর করতে পারবেন না।


4
এটি প্যাক্সিডিয়াবলোর উপরের চেয়ে ভাল উত্তর। স্ট্যান্ডার্ড এটিকে কেবল "প্রোগ্রামের নাম" বলে ডাকে, তবে এটি আমার জ্ঞানের কোথাও প্রয়োগ করা হয় না। ইউনিক্স কার্নেলগুলি শিশু প্রক্রিয়াতে অপরিবর্তিত () প্রয়োগ করতে স্ট্রিং অভিন্নভাবে পাস করে।
অ্যান্ডি রস

4
সি মান ') (execve' এটা বলতে পারি, কারণ এটি কথা কে না জানে সীমিত হয় ইত্যাদি দ্য POSIX মানক ( opengroup.org/onlinepubs/9699919799/functions/execve.html ) আছে আরো কিছু বলতে - এটিকে পরিষ্কার যেটি আরগভি [0] এ রয়েছে তা প্রক্রিয়াটির ঝাঁকুনিতে 'এক্সিকিভ ()' (বা সম্পর্কিত) সিস্টেম কল কার্যকর করে।
জোনাথন লেফলার

4
@ অ্যান্ডি, আপনি আপনার মতামত নির্দ্বিধায় :-) তবে আপনি প্রয়োগ সম্পর্কে ভুল wrong যদি কোনও বাস্তবায়ন মানটিকে অনুসরণ না করে তবে তা অ-সঙ্গতিপূর্ণ। এবং প্রকৃতপক্ষে, "প্রোগ্রামের নাম" কী হিসাবে এটি বাস্তবায়ন-সংজ্ঞায়িত, ইউএনআইএক্সের মতো একটি ওএস যতক্ষণ না নামটি নির্দিষ্ট করে ততক্ষণ তা মেনে চলে। এর মধ্যে রয়েছে কলগুলির এক্সিকিউটিভ পরিবারে আপনি যা চান তার সাথে আরজিভি [0] লোড করে একটি প্রোগ্রামের নাম নির্মোহভাবে জাল করতে সক্ষম হওয়া includes
paxdiablo

আরগভি [0] ("এটি প্রোগ্রামটির নাম উপস্থাপন করে") এবং আরজিভি [1..N] ("তারা প্রোগ্রামটির যুক্তি উপস্থাপন করে") বোঝায় তখন স্ট্যান্ডার্ডটিতে "প্রতিনিধিত্ব" শব্দের সৌন্দর্য এটিই। "আনলাডেন গেলা" একটি বৈধ প্রোগ্রামের নাম।
রিচার্ড পেনিংটন

9

সি ++ স্ট্যান্ডার্ড অনুসারে বিভাগ ৩.6.১:

আরজিভি [0] হ'ল এনটিএমবিএসের প্রাথমিক চরিত্রের নির্দেশক হবে যা প্রোগ্রামটি বা প্রার্থনার জন্য ব্যবহৃত নামটি উপস্থাপন করে ""

সুতরাং না, এটি নিশ্চিত নয়, কমপক্ষে মানক দ্বারা।


4
আমি ধরে নিলাম যে নালটি বাতিল বহু-বাইট স্ট্রিং?
paxdiablo

6

আইএসও-আইইসি 9899 বলেছেন:

5.1.2.2.1 প্রোগ্রাম সূচনা

মানটির মান argcশূন্যের চেয়ে বেশি হলে, নির্দেশিত স্ট্রিং argv[0]প্রোগ্রামটির নাম উপস্থাপন করে; argv[0][0]হোস্ট পরিবেশ থেকে প্রোগ্রামের নামটি উপলব্ধ না হলে নাল অক্ষর হবে shall তাহলে এর মান argcএক চেয়ে অনেক বেশী, স্ট্রিং দ্বারা প্রতি ইঙ্গিত argv[1]মাধ্যমে argv[argc-1]প্রতিনিধিত্ব প্রোগ্রাম পরামিতি

আমি এটি ব্যবহার করেছি:

#if defined(_WIN32)
  static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
  {
    return GetModuleFileNameA(NULL, pathName, (DWORD)pathNameCapacity);
  }
#elif defined(__linux__) /* elif of: #if defined(_WIN32) */
  #include <unistd.h>
  static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
  {
    size_t pathNameSize = readlink("/proc/self/exe", pathName, pathNameCapacity - 1);
    pathName[pathNameSize] = '\0';
    return pathNameSize;
  }
#elif defined(__APPLE__) /* elif of: #elif defined(__linux__) */
  #include <mach-o/dyld.h>
  static size_t getExecutablePathName(char* pathName, size_t pathNameCapacity)
  {
    uint32_t pathNameSize = 0;

    _NSGetExecutablePath(NULL, &pathNameSize);

    if (pathNameSize > pathNameCapacity)
      pathNameSize = pathNameCapacity;

    if (!_NSGetExecutablePath(pathName, &pathNameSize))
    {
      char real[PATH_MAX];

      if (realpath(pathName, real) != NULL)
      {
        pathNameSize = strlen(real);
        strncpy(pathName, real, pathNameSize);
      }

      return pathNameSize;
    }

    return 0;
  }
#else /* else of: #elif defined(__APPLE__) */
  #error provide your own implementation
#endif /* end of: #if defined(_WIN32) */

এবং তারপরে আপনাকে পথ থেকে এক্সিকিউটেবল নামটি বের করতে স্ট্রিংটি বিশ্লেষণ করতে হবে।


4
এই /proc/self/path/a.outসিমিলিংকটি সোলারিস 10 এবং তার বেশি ব্যবহারের জন্য কার্যকর হতে পারে।
পূর্বসূরি

কোডটির জন্য উত্সাহিত (এটি আদর্শ বা সঠিক হিসাবে বলছেন না, উদাহরণস্বরূপ উইন্ডোজে GetModuleFileNameWকোনও পথ পুনরুদ্ধার করতে সক্ষম হওয়া উচিত, তবে কোডের উপস্থিতিই সঠিক দিকনির্দেশনা গঠন করে)।
চিয়ার্স এবং এইচটিএইচ - আল্ফ

4

argv[0] !=এক্সিকিউটেবল নাম থাকার অ্যাপ্লিকেশন

  • অনেকগুলি শেল চেক করে লগইন শেল কিনা তা নির্ধারণ করে argv[0][0] == '-'। লগইন শেলগুলির বিভিন্ন বৈশিষ্ট্য রয়েছে, উল্লেখযোগ্যভাবে তারা কিছু ডিফল্ট ফাইল যেমন উত্স করে /etc/profile

    এটি সাধারণত ডিআইডি নিজেই থাকে বা gettyএটি নেতৃস্থানীয় যোগ করে -, এগুলিও দেখুন: /unix/299408/how-to-login-automatic-without-typing-the-root-username-or-password -ইন-বিল্ড / 300152 # 300152

  • মাল্টি-কল বাইনারিগুলি, সম্ভবত সর্বাধিক উল্লেখযোগ্য ব্যস্তবক্স । এই সিমিলিংক একাধিক নাম যেমন /bin/shand /bin/lsএবং একক বেনিফিটযোগ্য /bin/busybox, যা কোন সরঞ্জামটি ব্যবহার করতে হবে তা স্বীকার করে argv[0]

    এটি একক ছোট স্ট্যাটিকালি লিঙ্কযুক্ত এক্সিকিউটেবল যা একাধিক সরঞ্জামকে উপস্থাপন করে এবং এটি মূলত যে কোনও লিনাক্স পরিবেশে কাজ করবে makes

আরও দেখুন: /unix/315812/why-does-argv-incolve-the-program-name/315817

চলমান POSIX execveউদাহরণ যেখানে argv[0] !=সম্পাদনযোগ্য নাম

অন্যরা উল্লেখ করেছেন exec , তবে এখানে একটি চলমান উদাহরণ।

এসি

#define _XOPEN_SOURCE 700
#include <unistd.h>

int main(void) {
    char *argv[] = {"yada yada", NULL};
    char *envp[] = {NULL};
    execve("b.out", argv, envp);
}

বিসি

#include <stdio.h>

int main(int argc, char **argv) {
    puts(argv[0]);
}

তারপরে:

gcc a.c -o a.out
gcc b.c -o b.out
./a.out

দেয়:

yada yada

হ্যাঁ, argv[0]এটিও হতে পারে:

উবুন্টু 16.10 এ পরীক্ষা করা হয়েছে।


3

এই পৃষ্ঠাতে বলা হয়েছে:

আরগভি [0] উপাদানটি সাধারণত প্রোগ্রামটির নাম ধারণ করে তবে এটির উপর নির্ভর করা উচিত নয় - যাইহোক কোনও প্রোগ্রামের নিজের নাম না জানা এটি অস্বাভাবিক!

যাইহোক, অন্যান্য পৃষ্ঠাগুলি এটি সত্যই কার্যকর করার নাম হিসাবে ব্যাক আপ করে। এই এক বলে:

আপনি দেখতে পাবেন যে আরগভি [0] হ'ল প্রোগ্রামেরই পথ এবং নাম। এটি প্রোগ্রামটিকে নিজের সম্পর্কে তথ্য আবিষ্কার করতে দেয়। এটি প্রোগ্রাম আর্গুমেন্টের অ্যারেতে আরও একটি যোগ করে, সুতরাং কমান্ড-লাইন আর্গুমেন্টগুলি আনার সময় একটি সাধারণ ত্রুটি হ'ল আপনি যখন আরগভি [1] চান তখন আরগভি [0] কে দখল করতে হয়।


11
কিছু প্রোগ্রাম তাদের নামটি ব্যবহার করার জন্য ব্যবহৃত নামটি জানে না এই বিষয়টি গ্রহণ করে। আমি বিশ্বাস করি ব্যাসিবক্স ( ব্যস্তবক্স.না . / আউটআউট। Html ) এইভাবে কাজ করে। প্রয়োগযোগ্য অনেকগুলি কমান্ড-লাইন ইউটিলিটি প্রয়োগ করে exec কমান্ড-লাইনটি কী চালানো উচিত তা নির্ধারণ করতে এটি প্রতীকী লিঙ্ক এবং আরগভি [0] এর গোছা ব্যবহার করে
ট্রেন্ট

হ্যাঁ, আমার মনে আছে যে "বন্দুকযোপ" "জিজিপ" এর প্রতীকী লিঙ্ক ছিল এবং কীভাবে এটি কাজ করেছিল তা এক মুহুর্তের জন্য ভাবছিলাম।
ডেভিড থর্নলি

4
অনেক প্রোগ্রাম তথ্যের জন্য আরজিভি [0] এর দিকে তাকাচ্ছে; উদাহরণস্বরূপ, যদি নামের শেষ উপাদানটি কোনও ড্যাশ ('/ bin / -sh' দিয়ে শুরু হয়, উদাহরণস্বরূপ), তবে শেলটি লগইন শেল হিসাবে প্রোফাইল এবং অন্যান্য স্টাফ চালাবে।
জোনাথন লেফলার

4
@ জন: আমি ভেবেছিলাম লগইন শেল দিয়ে শুরু হয়েছিল argv[0]="-/bin/sh"? আমি যে সমস্ত মেশিন ব্যবহার করেছি, সে ক্ষেত্রে এটিই ঘটেছে।
মুহুর্তের

3

এটি প্রায় সর্বজনীন সম্মেলন বা মানক কিনা তা আমি নিশ্চিত নই, তবে যেভাবেই আপনি এটি মেনে চলা উচিত। যদিও আমি ইউনিক্স এবং ইউনিক্সের মতো সিস্টেমগুলির বাইরে এটি কখনও দেখেনি। ইউনিক্স পরিবেশে - এবং সম্ভবত বিশেষত পুরানো দিনগুলিতে - প্রোগ্রামগুলির নাম অনুসারে যেগুলি চাওয়া হয়েছে তার উপর নির্ভর করে উল্লেখযোগ্যভাবে বিভিন্ন আচরণ থাকতে পারে।

সম্পাদনা: আমি অন্য পোস্টগুলি থেকে আমার হিসাবে একই সাথে দেখছি যে কেউ এটি নির্দিষ্ট মানের থেকে আগত বলে চিহ্নিত করেছে, তবে আমি নিশ্চিত যে কনভেনশনটি দীর্ঘকাল মানটির পূর্বে রয়েছে।


4
আমি অবশ্যই আশাবাদী যে লোকেরা যদি আমার প্রতিক্রিয়াটিকে "চিহ্নিত" করে চলেছে তবে তারা এ সম্পর্কে তাদের পছন্দ নয় এমন কিছু ইঙ্গিত দেবে।
জো মাবেল

0

আপনি যদি ওয়ার্কবেঞ্চ দ্বারা একটি অ্যামিগা প্রোগ্রাম শুরু করেন argv [0] সেট করা হবে না, কেবল সিএলআই দ্বারা।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.