আমি কোনও প্রক্রিয়াটি কীভাবে ফাইলের অস্তিত্বের কথা চিন্তা করতে পারি?


31

আমার একটি প্রোগ্রাম রয়েছে যা এর সেটিংসটি সঞ্চয় করে ~/.config/myprogramযে আমি উভয় ইন্টারেক্টিভ এবং ব্যাচ কুইউং সিস্টেমের সাথে ব্যবহার করি। ইন্টারেক্টিভভাবে চলাকালীন, আমি এই প্রোগ্রামটিটি আমার কনফিগারেশন ফাইলগুলি ব্যবহার করতে চাই (এবং এটি হয়)। তবে ব্যাচ মোডে চলার সময় কনফিগারেশন ফাইলগুলি প্রয়োজনীয় নয় কারণ আমি কমান্ড-লাইন বিকল্পগুলি নির্দিষ্ট করে যা সমস্ত প্রাসঙ্গিক সেটিংস ওভাররাইট করে। আরও, নেটওয়ার্কের মাধ্যমে কনফিগারেশন ফাইলগুলিতে অ্যাক্সেস প্রোগ্রামের প্রারম্ভকালীন সময়টিকে কয়েক সেকেন্ড বৃদ্ধি করে; যদি ফাইলগুলির অস্তিত্ব না থাকে তবে প্রোগ্রামটি আরও দ্রুত চালু হয় (প্রতিটি কাজ যেমন কেবল এক মিনিট সময় নেয় তাই ব্যাচের চাকরির থ্রুটপুটটিতে এটির প্রভাব ফেলবে)। তবে আমিও প্রোগ্রামটি ইন্টারেক্টিভভাবে ব্যবহার করার কারণে, আমি আমার কনফিগারেশন ফাইলগুলি সারাক্ষণ সরিয়ে / মুছে ফেলতে চাই না। কখন আমার ব্যাচের কাজগুলি ক্লাস্টারে নির্ধারিত হবে (অন্যান্য ব্যবহারকারীর ব্যবহারের ভিত্তিতে),

(একদিকে: নেটওয়ার্ক ফাইলের পারফরম্যান্সটি এত ধীরে ধীরে সম্ভবত একটি বাগ, তবে আমি ক্লাস্টারের কেবলমাত্র একজন ব্যবহারকারী, তাই আমি কেবল এটির আশপাশে কাজ করতে পারি, এটি ঠিক করতে পারি না))

আমি প্রোগ্রামটির এমন একটি সংস্করণ তৈরি করতে পারি যা ব্যাচ ব্যবহারের জন্য কনফিগারেশন ফাইলগুলি পড়েনি (বা না করার জন্য একটি কমান্ড-লাইন বিকল্প রয়েছে) তবে এই প্রোগ্রামটির বিল্ডিং পরিবেশটি খারাপ-ইঞ্জিনিয়ারড এবং সেট আপ করা শক্ত। আমি আমার সিস্টেমের প্যাকেজ ম্যানেজারের মাধ্যমে ইনস্টল করা বাইনারিগুলি ব্যবহার করতে পছন্দ করব।

আমার কনফিগারেশন ফাইলের অস্তিত্ব নেই (প্রোগ্রাম পরিবর্তন না করে) কীভাবে এই প্রোগ্রামটির বিশেষ উদাহরণগুলি চালিত করব? আমি ফর্মটি একটি মোড়কের জন্য আশা করছি pretendfiledoesntexist ~/.config/myprogram -- myprogram --various-options..., তবে আমি অন্যান্য সমাধানের জন্য উন্মুক্ত।


2
আপনি এটি ব্যবহারকারী হিসাবে চালাতে পারেন যার ফাইলটি পড়ার অনুমতি নেই।
প্রিমন

1
@psimon ক্লাস্টারের "কেবলমাত্র একজন ব্যবহারকারী" হিসাবে আমি আমার ব্যাচের কাজটি চালানোর জন্য কোনও নতুন ব্যবহারকারী তৈরি করতে পারি না। যদিও এটি একটি চতুর ধারণা, এবং যদি এর চেয়ে ভাল আরও কোন পরামর্শ না থাকে তবে আমি এটি ক্লাস্টার অ্যাডমিনটিকে আমার জন্য করব।
জেফ্রি বসবুম

অথবা একটি স্ক্রিপ্ট সেট আপ করুন যা প্রথমে কনফিগার ফাইলটির নাম পরিবর্তন করে, প্রোগ্রামটি চালায় এবং তারপরে আবার কনফিগার ফাইলটির পুনরায় নামকরণ করে।
প্রিমন

@ সাইমন আমার ধারণা আমি আরও পরিষ্কার হতে পারতাম: আমি আমার ব্যাচের কাজগুলি ক্লাস্টারে কখন নির্ধারিত হবে তার উপর নির্ভর করে আমি একই সাথে ইন্টারেক্টিভ এবং ব্যাচ মোডে প্রোগ্রামটি ব্যবহার করছিলাম।
জেফ্রি বসবুম

1
হ্যাঁ, এটির গতিশীলভাবে সংযুক্ত থাকলে আপনি একটি LD_PRELOADহুক ব্যবহার করতে পারেন । বিকল্পটির চেয়ে এটি সহজ (আপনি যদি এক ঘন্টার মধ্যে দু'বারের মধ্যে এটি প্রয়োগ করতে পারেন) তবে এটি ptrace। এটি করার জন্য আপনি সম্ভবত ফ্যাকেরুটও ব্যবহার করতে পারেন (যা এলডিপ্রেলএড, আমি বিশ্বাস করি)।
ডারোবার্ট

উত্তর:


33

এই প্রোগ্রামটি সম্ভবত সেই ফাইলটির পথটিকে সমাধান করে $HOME/.config/myprogram। সুতরাং আপনি এটি বলতে পারেন যে আপনার হোম ডিরেক্টরিটি অন্য কোথাও রয়েছে, যেমন:

HOME=/nowhere your-program

এখন, আপনার প্রোগ্রামটি আপনার হোম ডিরেক্টরিতে অন্য কিছু সংস্থান দরকার। আপনি যদি তা জানেন তবে আপনি সেখানে প্রয়োজনীয় সংস্থানটির লিঙ্ক সহ আপনার প্রোগ্রামের জন্য একটি জাল বাড়ি তৈরি করতে পারেন।

mkdir -p ~/myprogram-home/.config
ln -s ~/.Xauthority ~/myprogram-home/
...
HOME=~/myprogram-home myprogram

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

28

অন্য সমস্ত কিছু যদি ব্যর্থ হয়, এমন একটি মোড়ক লাইব্রেরি লিখুন যা আপনি ব্যবহার করে ইনজেক্ট করবেন LD_PRELOADযাতে কলটি open("/home/you/my-program/config.interactive")আটকানো হয় তবে অন্য যে কোনও মাধ্যমে যায়। এটি যে কোনও ধরণের প্রোগ্রাম এমনকি শেল স্ক্রিপ্টগুলির জন্য কাজ করে, কারণ এটি সিস্টেম কলগুলি ফিল্টার করবে।

extern int errno;

int open(const char *pathname, int flags)
{
  char *config_path = get_config_file_path();
  if (!strstr(pathname, config_path))
  {
    return get_real_open(pathname, flags);
  }
  else
  {
    errno = ENOENT;
    return -1;
  }
}

দ্রষ্টব্য: আমি এই কোডটি পরীক্ষা করি নি, এবং errnoঅংশটি কাজ করে কিনা আমি 100% নিশ্চিত নই ।

fakerootএটি কল getuid(2)এবং এর জন্য কী করে তা দেখুন stat(2)

মূলত, লিঙ্কারটি সেই অ্যাপ্লিকেশনটিকে আপনার লাইব্রেরিতে লিঙ্ক করবে, যা openপ্রতীকটিকে ওভাররাইড করে । যেহেতু আপনি openনিজের লাইব্রেরিতে নামকরণ করা দুটি পৃথক ফাংশন ব্যবহার করতে পারবেন না , তাই আপনাকে এটি দ্বিতীয় অংশে পৃথক করতে হবে (যেমন get_real_open) যা মূল openকলটির সাথে সংযুক্ত হয়ে যাবে।

মূল: ./Application

Application -----> libc.so
            open()

বাধাপ্রাপ্ত: LD_PRELOAD=yourlib_wrap.so ./Application

Application -----> yourlib_wrap.so --------------> yourlib_impl.so -----> libc.so
            open()                 get_real_open()                 open()

সম্পাদনা করুন: আপাতদৃষ্টিতে এমন একটি ldপতাকা রয়েছে যা আপনি সক্ষম করতে পারবেন ( --wrap <symbol>) যা আপনাকে ডাবল লিঙ্কিংয়ের অবলম্বন না করে মোড়কে লিখতে দেয়:

/* yourlib.c */
#include <stdio.h>

int __real_open(const char *pathname, int flags)

int __wrap_open(const char *pathname, int flags)
{
  char *config_path = get_config_file_path();
  if (!strstr(pathname, config_path))
  {
    /* the undefined reference here will resolve to "open" at linking time */
    return __real_open(pathname, flags);
  }
  else
  {
    errno = ENOENT;
    return -1; 
  }
}

2

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


আমার সাম্প্রতিক সম্পাদনাটি দেখুন: আমি ব্যাচের সময়সূচীটি নিয়ন্ত্রণ করি না, তাই আমি একই সাথে প্রোগ্রামটি ইন্টারেক্টিভভাবে এবং ব্যাচের কাজের অংশ হিসাবে ব্যবহার করতে পারি।
জেফ্রি বসবুম

1

এটি ইউনিয়ন / আফস দ্বারা সম্ভব হওয়া উচিত। আপনি chrootপ্রক্রিয়া জন্য একটি পরিবেশ তৈরি । আপনি আসল ডিরেক্টরিটি কেবল পঠনযোগ্য স্তর হিসাবে ব্যবহার করেন এবং তার উপরে একটি খালি রাখুন। তারপরে আপনি ইউনিভেন্স ভলিউমটিকে chrootপরিবেশের সম্পর্কিত ডিরেক্টরিতে মাউন্ট করবেন এবং সেখানে ফাইলটি মুছুন। প্রক্রিয়া এটি দেখতে পাবে না তবে অন্যরা সবাই তা করে।


0

উদাহরণস্বরূপ কনফিগারেশন ফাইলটির নাম পরিবর্তন করুন config.interactive। যেমন খালি আরও একটি ফাইল তৈরি করুন config.script

configআপনার যেকোন আসল কনফিগারেশন প্রয়োজন এবং আপনার অ্যাপ্লিকেশনটি চালানোর জন্য একটি সফট লিঙ্ক (বা অ্যাপ্লিকেশনটি কনফিগারেশন ফাইল হিসাবে যা কিছু প্রত্যাশা করে) তৈরি করুন।

ln -s config.interactive config

পরে আপনার লিঙ্কটি পরিপাটি করে রাখতে ভুলবেন না।


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

1
ডোহ! আমার আরও দ্রুত টাইপ করা দরকার। এটি একটি বড় অ্যাপ্লিকেশন? এটি কি কোনও ক্রুটে স্থানান্তরিত করা যেতে পারে এবং সেখান থেকে ইন্টারেক্টিভভাবে চালানো যেতে পারে? আমি মনে করি প্রোগ্রামটি কীসের সাথে ইন্টারঅ্যাক্ট করে তার উপর এটি নির্ভর করে। এটি একটি ক্রুটের মধ্যেও প্রয়োজনীয় সমস্ত কিছু পাওয়া খুব ক্লান্তিকর কাজ হতে পারে। (আমি মনে করি আমি সেই বিকল্পটি থেকে নিজেকে কথা বলি!)
গ্যারেথ দ্য রেড

0

আপনার প্রোগ্রামটি কনফিগারেশন ফাইলটি কীভাবে ব্যবহার করে তা আপনি যদি নির্দিষ্টভাবে চিহ্নিত করেছেন তবে আমি এটিকে এড়িয়ে চলেছি। অনেক প্রোগ্রাম (যেমন bashএবং vi) শুরু হওয়ার সাথে সাথে কনফিগারেশন ফাইলের জন্য পরীক্ষা করবে; যদি ফাইলটি বিদ্যমান থাকে তবে এটি পড়ুন এবং এটি বন্ধ করুন। এই প্রোগ্রামগুলি আর কখনও এই আরম্ভকরণ ফাইলগুলিতে অ্যাক্সেস করে না। আপনার প্রোগ্রামটি যদি এর মতো হয় তবে পড়ুন।

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

DELAY_TIME=1
REALPATH="~/.config/myprogram"
HOLDPATH="${REALPATH}.hold"

mv "$REALPATH" "$HOLDPATH"
(sleep "$DELAY_TIME"; mv "$HOLDPATH" "$REALPATH")&
myprogram

এটি কনফিগারেশন ফাইলটিকে অন্যদিকে সরিয়ে দেয়, তবে এটি পরে চলে গেলেও এটি এক সেকেন্ড পরে সরিয়ে দেয় myprogram। এটি সময়ের একটি খুব সংক্ষিপ্ত উইন্ডো তৈরি করে যার সময় ফাইলটি অনুপলব্ধ থাকে - এই উইন্ডোটির সময় আপনি ইন্টারেক্টিভভাবে প্রোগ্রামটি চালাবেন এমন সম্ভাবনা কী? (যদি আপনি এটি করেন, আপনি কেবল প্রস্থান এবং পুনঃসূচনা করতে পারেন এবং কনফিগার ফাইলটি সম্ভবত আবার ফিরে আসবে))

এটি একটি রেসের শর্ত তৈরি করে; প্রোগ্রামটি ফাইলটি খোলার জন্য যদি খুব বেশি সময় নেয় তবে এটি আসল ফাইলটি পেতে পারে। যদি এটি প্রায়শই যথেষ্ট হয় তবে এটি একটি সমস্যা, কেবলমাত্র DELAY_TIME এর মান বাড়ান।


1
সবচেয়ে খারাপ জিনিসটি কী ভুল হতে পারে? আমি ঘটনাক্রমে দেখেছি। উৎপাদন.
হেন্ক ল্যাঙ্গভেল্ড

-1

আমি স্টিফেন এর উত্তর, কিন্তু এটি হবে রত যেকোনো ফাইল বিশ্বাসী মধ্যে কোনো প্রোগ্রাম খালি - (কারণ তার dentry সাময়িকভাবে একটি ফাইল যে আসলে খালি করার পয়েন্ট) :

cat <./test.txt
###OUTPUT###
notempty

mount --bind /dev/null ./test.txt
cat <./test.txt
###NO OUTPUT###

umount ./test.txt
cat <./test.txt
###OUTPUT###
notempty

আপনিও করতে পারেন:

mount --bind ./someotherconfig.conf ./unwanted.conf

যদি তুমি চাইতে.


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

@ স্কট - আমি একমত নই - এর আগে প্রতিটি অন্য উত্তর mvফাইলটি আইংগুলিতে কিছুটা পরিবর্তনের প্রস্তাব দেয় - যার ফলস্বরূপ দন্তকে প্রভাবিত করা ছাড়া অন্য পরিণতিও হতে পারে যেমন ফাইল বা অন্যদেরকে কেটে ফেলা - ইত্যাদি, যদিও এটি কেবল কিছুই নয়। তবুও আমি উচিত unshareযে mountআমি অনুমান ...
mikeserv
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.