অস্থায়ী ফোল্ডার যা প্রক্রিয়া প্রস্থানের পরে স্বয়ংক্রিয়ভাবে ধ্বংস হয়ে যায়


10

আমরা কি অস্থায়ী ফাইলগুলির মতো অস্থায়ী ফোল্ডারগুলি ব্যবহার করতে পারি?

TMP=$(mktemp ... )
exec 3<>$TMP
rm $TMP

cat <&3

এই শেলটি প্রস্থান করার পরে কোনটি স্বয়ংক্রিয়ভাবে ধ্বংস হয়ে যাবে?


উত্তর:


12

একটি অস্থায়ী ফাইলের ক্ষেত্রে, প্রশ্নের আপনার উদাহরণটি এটি তৈরি করবে, তারপরে ডিরেক্টরি থেকে এটি লিঙ্কমুক্ত করুন (এটি "অদৃশ্য হয়ে যাবে"), এবং যখন স্ক্রিপ্ট ফাইলডিসিপিটারটি বন্ধ করবে (সম্ভবত সমাপ্তির পরে), ফাইলটি নেওয়া স্থান সিস্টেম দ্বারা পুনরুদ্ধারযোগ্য হবে। এটি সি এর মতো ভাষায় অস্থায়ী ফাইলগুলি মোকাবেলার একটি সাধারণ উপায় is

এটি যতদূর আমি জানি, একইভাবে ডিরেক্টরি খোলা সম্ভব নয়, অন্তত কোনওভাবেই ডিরেক্টরিটি ব্যবহারযোগ্য করে তুলবে না।

কোনও স্ক্রিপ্টের সমাপ্তির সময় অস্থায়ী ফাইল এবং ডিরেক্টরিগুলি মুছে ফেলার একটি সাধারণ উপায় হল ক্লিনআপ EXITট্র্যাপ ইনস্টল করা । নীচে প্রদত্ত কোড উদাহরণগুলি ফাইলডিজিপেক্টরগুলিকে পুরোপুরি জগল করা এড়িয়ে চলে।

tmpdir=$(mktemp -d)
tmpfile=$(mktemp)

trap 'rm -f "$tmpfile"; rm -rf "$tmpdir"' EXIT

# The rest of the script goes here.

অথবা আপনি একটি ক্লিনআপ ফাংশন কল করতে পারেন:

cleanup () {
    rm -f "$tmpfile"
    rm -rf "$tmpdir"
}

tmpdir=$(mktemp -d)
tmpfile=$(mktemp)

trap cleanup EXIT

# The rest of the script goes here.

সিগন্যাল (যা আটকাতে পারে না) EXITপাওয়ার পরে ফাঁদ কার্যকর করা হবে না KILL, যার অর্থ হল যে তখন কোনও পরিষ্কার-পরিচ্ছন্নতা হবে না। তবে চালানো হবে যখন একটি কারণে সসীম INTবা TERMসংকেত (যদি দিয়ে চলছে bashবা ksh, অন্যান্য শাঁস আপনি পরে এই সংকেত যোগ করতে পারেন EXITমধ্যে trapকমান্ড লাইন), অথবা যখন স্বাভাবিকভাবে কারণে স্ক্রিপ্ট শেষে আসার অথবা একটি নির্বাহ করার থেকে প্রস্থান exitকল করুন।


5
এটি কেবল শেল নয় যা ইতিমধ্যে লিঙ্কযুক্ত অস্থায়ী ডিরেক্টরি ব্যবহার করতে পারে না - সি প্রোগ্রামগুলিও করতে পারে না। সমস্যা হ'ল লিঙ্কযুক্ত ডিরেক্টরিতে সেগুলিতে ফাইল থাকতে পারে না। আপনার কর্মক্ষম ডিরেক্টরি হিসাবে একটি লিঙ্কযুক্ত লিখিত ফাঁকা ডিরেক্টরি থাকতে পারে তবে একটি ফাইল তৈরির যে কোনও প্রচেষ্টা একটি ত্রুটি দেবে।
ডারোবার্ট

1
@derobert এবং এই ধরনের একটি লিঙ্ক মুক্ত ডিরেক্টরির এমনকি নেই .এবং ..এন্ট্রি। (লিনাক্সে পরীক্ষিত, প্ল্যাটফর্মগুলির জুড়ে এটি সামঞ্জস্যপূর্ণ কিনা তা আমি জানি না))
ক্যাস্পারড


1
দ্রষ্টব্য যে স্ক্রিপ্ট exec another-commandস্পষ্টভাবে কল করলে এক্সিট ট্র্যাপটি কার্যকর হয় না ।
স্টাফেন চেজেলাস


6

আপনার স্ক্রিপ্টটি শেষ হয়ে গেলে কার্যকর করা হবে এমন একটি শেল-ফাংশন লিখুন। নীচের উদাহরণে আমি এটিকে 'ক্লিনআপ' বলি এবং প্রস্থান স্তরগুলিতে মৃত্যুর জন্য ফাঁদ সেট করি, যেমন: 0 1 2 3 6

trap cleanup 0 1 2 3 6

cleanup()
{
  [ -d $TMP ] && rm -rf $TMP
}

আরও তথ্যের জন্য এই পোস্টটি দেখুন ।


এরাই না "প্রস্থান মাত্রা" কিন্তু সংকেত নম্বর এবং প্রশ্নের উত্তর আপনি লিঙ্ক করছি ঠিক যে ব্যাখ্যা করে। এই ফাঁদটি cleanupএকটি পরিষ্কার প্রস্থান (0) এর আগে এবং সাইনআপ (1), সাইন ইন (2), সাইনকিউট (3) এবং স্যাব্যাবআরটি (6) পাওয়ার পরে চলবে। এটা হবে না চালানোর cleanupযখন SIGTERM, SIGSEGV, SIGKILL, SIGPIPE, ইত্যাদি কারণ স্ক্রিপ্ট প্রস্থানের এটা স্পষ্ট ঘাটতি নেই।
মোসভি

6

আপনি এটির মধ্যে chdir করতে পারেন এবং তারপরে এটি সরিয়ে ফেলতে পারেন, তবে আপনি যদি এর ভিতরে কোনও পাথ ব্যবহার করার চেষ্টা না করেন তবে:

#! /bin/sh
dir=`mktemp -d`
cd "$dir"
exec 4>file 3<file
rm -fr "$dir"

echo yes >&4    # OK
cat <&3         # OK

cat file        # FAIL
echo yes > file # FAIL

আমি পরীক্ষা করে দেখিনি, তবে সি সিস্টেমে ওপেনট (2) ব্যবহার করার সময় এটি সম্ভবত একই সমস্যা যা ফাইল সিস্টেমে আর বিদ্যমান নেই।

যদি আপনি মূল এবং লিনাক্সে থাকেন তবে আপনি একটি পৃথক নেমস্পেস এবং এর mount -t tmpfs tmpfs /dirভিতরে খেলতে পারেন ।

ক্যানোনিকাল উত্তরগুলি (এক্সিটের উপর একটি ফাঁদ সেট করুন) কাজ করে না যদি আপনার স্ক্রিপ্টটি অশুচি প্রস্থান করতে বাধ্য করা হয় (যেমন, সিগিলের সাহায্যে); এটি সংবেদনশীল ডেটা চারদিকে ঝুলতে পারে।

হালনাগাদ:

এখানে একটি ছোট্ট ইউটিলিটি যা নেমস্পেস পদ্ধতির প্রয়োগ করে। এটি দিয়ে সংকলিত করা উচিত

cc -Wall -Os -s chtmp.c -o chtmp

এবং প্রদত্ত CAP_SYS_ADMINফাইলের ক্ষমতা (মূল হিসাবে)

setcap CAP_SYS_ADMIN+ep chtmp

চালানোর সময় (সাধারণ হিসাবে) ব্যবহারকারী হিসাবে

./chtmp command args ...

এটি তার ফাইল সিস্টেমের নেমস্পেসটি /proc/sysvipcভাগ করে নেবে, একটি টিএমপিএস ফাইল ফাইলটি মাউন্ট করবে , এতে chdir করবে এবং commandপ্রদত্ত আর্গুমেন্টগুলি দিয়ে চালাবে । ক্ষমতা উত্তরাধিকারী commandহবে নাCAP_SYS_ADMIN

এই ফাইল সিস্টেমটি অন্য কোনও প্রক্রিয়া থেকে শুরু না হয়ে অ্যাক্সেসযোগ্য হবে না commandএবং এটি commandকীভাবে ঘটেছিল তা বিবেচনা না করে যখন এটির শিশুরা মারা যায় তখন এটি যাদুতে ( তার ভিতরে তৈরি হওয়া সমস্ত ফাইল সহ) অদৃশ্য হয়ে যায় । লক্ষ্য করুন যে এটি কেবল মাউন্ট নেমস্পেসের অংশীদারিত্ব করছে - commandএকই ব্যবহারকারীর দ্বারা চালিত অন্যান্য প্রক্রিয়াগুলির মধ্যে কোনও শক্ত বাধা নেই ; তারা এখনও পারেন মাধ্যমে তার নামস্থান ভিতরে ছিঁচকে চোর পারে ptrace(2), /proc/PID/cwdবা অন্যান্য উপায়ে।

"অকেজো" এর হাইজ্যাকিং /proc/sysvipcঅবশ্যই নিরীহ, তবে বিকল্পটি হ'ল /tmpফাঁকা ডিরেক্টরিগুলি স্প্যাম করা যেগুলি সরাতে হবে বা কাঁটাচামচ এবং অপেক্ষা সহ এই ছোট প্রোগ্রামটিকে ব্যাপকভাবে জটিল করতে হবে। বিকল্প হিসাবে, dirউদাহরণস্বরূপে পরিবর্তন করা যেতে পারে। /mnt/chtmpএবং এটি ইনস্টলেশনে রুট দ্বারা তৈরি করা হয়েছে; এটিকে ব্যবহারকারী-কনফিগারযোগ্য করে তুলবেন না এবং এটি ব্যবহারকারীর মালিকানাধীন পথে সেট করবেন না কারণ এটি আপনাকে ফাঁস এবং অন্যান্য লোমযুক্ত জিনিসগুলিকে সময় ব্যয় করার পক্ষে উপযুক্ত নয়।

chtmp.c

#define _GNU_SOURCE
#include <err.h>
#include <sched.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/mount.h>
int main(int argc, char **argv){
        char *dir = "/proc/sysvipc";    /* LOL */
        if(argc < 2 || !argv[1]) errx(1, "usage: %s prog args ...", *argv);
        argv++;
        if(unshare(CLONE_NEWNS)) err(1, "unshare(CLONE_NEWNS)");
        /* "modern" systemd remounts all mount points MS_SHARED
           see the NOTES in mount_namespaces(7); YUCK */
        if(mount("none", "/", 0, MS_REC|MS_PRIVATE, 0))
                err(1, "mount(/, MS_REC|MS_PRIVATE)");
        if(mount("tmpfs", dir, "tmpfs", 0, 0)) err(1, "mount(tmpfs, %s)", dir);
        if(chdir(dir)) err(1, "chdir %s", dir);
        execvp(*argv, argv);
        err(1, "execvp %s", *argv);
}

1
এমনকি যদি আপনি রুট না হন তবে আপনি নতুন ব্যবহারকারী নেমস্পেস তৈরি করে এর ভিতরে টিএমপিএফ মাউন্ট করে নেমস্পেস দিয়ে এটি করতে পারেন। নতুন দিরের বাইরের বিশ্বে চোরাচালান অ্যাক্সেস কিছুটা জটিল তবে এটি হওয়া উচিত।
আর .. গিথহাব বন্ধ করুন ICE

এটি এখনও CAP_SYS_ADMIN প্রয়োজন। আমার কাছে একটি ছোট সেটক্যাপ-সক্ষম ইউটিলিটি ধারণা রয়েছে যা এটি করবে, আমি এটির সাথে উত্তরটি আপডেট করব।
কুইবার্ট

1
কার্নেলটি এটি অস্বীকার করার জন্য লক করা না থাকলে ব্যবহারকারীর নেমস্পেস তৈরি করা কোনও সুবিধাযুক্ত ক্রিয়াকলাপ নয়। অন্তর্নিহিত নকশাটি এমন যে সাধারণ ব্যবহারকারীদের কোনও বিশেষ ক্ষমতা ছাড়াই অনুমতি দেওয়া নিরাপদ বলে মনে করা হয়। তবে পর্যাপ্ত আক্রমণের পৃষ্ঠ / ঝুঁকি রয়েছে যা অনেকগুলি ডিস্ট্রো এটি অক্ষম করে, আমি মনে করি।
আর .. গিটহাব বন্ধ করুন ICE

আমি টার্মিনাল চেষ্টা করেছি। কিছু অস্থায়ী দির, rm $PWDকাজ, শেল এখনও সেই দির মধ্যে রয়েছে। তবে এই "ফোল্ডারে" কোনও নতুন ফাইল রাখা যাবে না। কেবলমাত্র আপনি যা করতে পারেন তা ফাইল এবং 3 এবং 4 দিয়ে পড়া / লিখতে পারেন। সুতরাং এটি এখনও "অস্থায়ী ফাইল", "অস্থায়ী ফোল্ডার" নয়।
বব জনসন

@ BobJohnson এটি আমার উত্তরটিতে ইতিমধ্যে যা বলেছিলাম তার থেকে আলাদা নয় ;-)
কোবার্ট

0

আপনি কি একটি নির্দিষ্ট শেল প্রয়োজন?

Zsh যদি কোনও বিকল্প হয় তবে দয়া করে পড়ুন zshexpn(1):

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

[...]

অন্য সমস্যা দেখা দেয় যে কোনও সময় বিকল্পের সাথে একটি চাকরির জন্য অস্থায়ী ফাইলের প্রয়োজন হয় যা শেল দ্বারা অস্বীকার করা হয়, যেখানে প্রতিস্থাপনযুক্ত কমান্ডের শেষে &!বা &|উপস্থিত হয় সে ক্ষেত্রে including সেক্ষেত্রে শেলটির কাজের কোনও স্মৃতি নেই বলে অস্থায়ী ফাইলটি পরিষ্কার করা হবে না। একটি কার্যপ্রণালী হ'ল একটি সাব-শেল ব্যবহার করা, উদাহরণস্বরূপ,

(mycmd =(myoutput)) &!

যেহেতু কাঁটাযুক্ত সাবશેল কমান্ডটি শেষ করার জন্য অপেক্ষা করবে তারপরে অস্থায়ী ফাইলটি সরিয়ে ফেলবে।

একটি যথাযথ দৈর্ঘ্যের জন্য প্রক্রিয়া প্রতিস্থাপনের স্থায়ীত্ব নিশ্চিত করার জন্য একটি সাধারণ কর্মসূচি হ'ল এটি একটি বেনাম শেল ফাংশনে (ফাংশনের সুযোগের সাথে সাথে চালানো শেল কোডের একটি অংশ) প্যারামিটার হিসাবে পাস করা pass উদাহরণস্বরূপ, এই কোড:

() {
   print File $1:
   cat $1
} =(print This be the verse)

নিম্নলিখিত অনুরূপ কিছু আউটপুট

File /tmp/zsh6nU0kS:
This be the verse

উদাহরণস্বরূপ আমি একটি ফাইল ডিক্রিপ্ট করার জন্য রাইফেল (রেঞ্জার ফাইল ম্যানেজারের অংশ) এ এটি ব্যবহার করি এবং তারপরে অস্থায়ী ফাইলটিতে রাইফেল চালাতে পারি, যা সাবপ্রসেসগুলি শেষ হয়ে গেলে মুছে যায়। (সেট করতে ভুলবেন না $TERMCMD)

# ~/.config/ranger/rifle.conf
...
!ext exe, mime octet-stream$, has gpg, flag t = () { rifle -f F "$1" } =(gpg -dq "$1")
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.