উত্তর:
একটি অস্থায়ী ফাইলের ক্ষেত্রে, প্রশ্নের আপনার উদাহরণটি এটি তৈরি করবে, তারপরে ডিরেক্টরি থেকে এটি লিঙ্কমুক্ত করুন (এটি "অদৃশ্য হয়ে যাবে"), এবং যখন স্ক্রিপ্ট ফাইলডিসিপিটারটি বন্ধ করবে (সম্ভবত সমাপ্তির পরে), ফাইলটি নেওয়া স্থান সিস্টেম দ্বারা পুনরুদ্ধারযোগ্য হবে। এটি সি এর মতো ভাষায় অস্থায়ী ফাইলগুলি মোকাবেলার একটি সাধারণ উপায় 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
কল করুন।
.
এবং ..
এন্ট্রি। (লিনাক্সে পরীক্ষিত, প্ল্যাটফর্মগুলির জুড়ে এটি সামঞ্জস্যপূর্ণ কিনা তা আমি জানি না))
exec another-command
স্পষ্টভাবে কল করলে এক্সিট ট্র্যাপটি কার্যকর হয় না ।
আপনার স্ক্রিপ্টটি শেষ হয়ে গেলে কার্যকর করা হবে এমন একটি শেল-ফাংশন লিখুন। নীচের উদাহরণে আমি এটিকে 'ক্লিনআপ' বলি এবং প্রস্থান স্তরগুলিতে মৃত্যুর জন্য ফাঁদ সেট করি, যেমন: 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, ইত্যাদি কারণ স্ক্রিপ্ট প্রস্থানের এটা স্পষ্ট ঘাটতি নেই।
আপনি এটির মধ্যে 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);
}
rm $PWD
কাজ, শেল এখনও সেই দির মধ্যে রয়েছে। তবে এই "ফোল্ডারে" কোনও নতুন ফাইল রাখা যাবে না। কেবলমাত্র আপনি যা করতে পারেন তা ফাইল এবং 3 এবং 4 দিয়ে পড়া / লিখতে পারেন। সুতরাং এটি এখনও "অস্থায়ী ফাইল", "অস্থায়ী ফোল্ডার" নয়।
আপনি কি একটি নির্দিষ্ট শেল প্রয়োজন?
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")