আমি সি ++ / লিনাক্সে একাধিক ডিরেক্টরি তৈরির সহজ উপায় চাই।
উদাহরণস্বরূপ আমি ডিরেক্টরিতে একটি ফাইল lola.file সংরক্ষণ করতে চাই:
/tmp/a/b/c
তবে ডিরেক্টরিগুলি না থাকলে আমি সেগুলি স্বয়ংক্রিয়ভাবে তৈরি করা চাই। একটি কাজের উদাহরণ নিখুঁত হবে।
আমি সি ++ / লিনাক্সে একাধিক ডিরেক্টরি তৈরির সহজ উপায় চাই।
উদাহরণস্বরূপ আমি ডিরেক্টরিতে একটি ফাইল lola.file সংরক্ষণ করতে চাই:
/tmp/a/b/c
তবে ডিরেক্টরিগুলি না থাকলে আমি সেগুলি স্বয়ংক্রিয়ভাবে তৈরি করা চাই। একটি কাজের উদাহরণ নিখুঁত হবে।
উত্তর:
সি ++ 17 বা তার পরে, <filesystem>ফাংশন সহ স্ট্যান্ডার্ড শিরোনাম রয়েছে
std::filesystem::create_directories
যা আধুনিক সি ++ প্রোগ্রামগুলিতে ব্যবহার করা উচিত। যদিও C ++ স্ট্যান্ডার্ড ফাংশনগুলির মধ্যে POSIX- নির্দিষ্ট স্পষ্টত অনুমতি (মোড) যুক্তি নেই।
তবে, এখানে একটি সি ফাংশন যা সি ++ সংকলকগুলির সাথে সংকলিত হতে পারে।
/*
@(#)File: mkpath.c
@(#)Purpose: Create all directories in path
@(#)Author: J Leffler
@(#)Copyright: (C) JLSS 1990-2020
@(#)Derivation: mkpath.c 1.16 2020/06/19 15:08:10
*/
/*TABSTOP=4*/
#include "posixver.h"
#include "mkpath.h"
#include "emalloc.h"
#include <errno.h>
#include <string.h>
/* "sysstat.h" == <sys/stat.h> with fixup for (old) Windows - inc mode_t */
#include "sysstat.h"
typedef struct stat Stat;
static int do_mkdir(const char *path, mode_t mode)
{
Stat st;
int status = 0;
if (stat(path, &st) != 0)
{
/* Directory does not exist. EEXIST for race condition */
if (mkdir(path, mode) != 0 && errno != EEXIST)
status = -1;
}
else if (!S_ISDIR(st.st_mode))
{
errno = ENOTDIR;
status = -1;
}
return(status);
}
/**
** mkpath - ensure all directories in path exist
** Algorithm takes the pessimistic view and works top-down to ensure
** each directory in path exists, rather than optimistically creating
** the last element and working backwards.
*/
int mkpath(const char *path, mode_t mode)
{
char *pp;
char *sp;
int status;
char *copypath = STRDUP(path);
status = 0;
pp = copypath;
while (status == 0 && (sp = strchr(pp, '/')) != 0)
{
if (sp != pp)
{
/* Neither root nor double slash in path */
*sp = '\0';
status = do_mkdir(copypath, mode);
*sp = '/';
}
pp = sp + 1;
}
if (status == 0)
status = do_mkdir(path, mode);
FREE(copypath);
return (status);
}
#ifdef TEST
#include <stdio.h>
#include <unistd.h>
/*
** Stress test with parallel running of mkpath() function.
** Before the EEXIST test, code would fail.
** With the EEXIST test, code does not fail.
**
** Test shell script
** PREFIX=mkpath.$$
** NAME=./$PREFIX/sa/32/ad/13/23/13/12/13/sd/ds/ww/qq/ss/dd/zz/xx/dd/rr/ff/ff/ss/ss/ss/ss/ss/ss/ss/ss
** : ${MKPATH:=mkpath}
** ./$MKPATH $NAME &
** [...repeat a dozen times or so...]
** ./$MKPATH $NAME &
** wait
** rm -fr ./$PREFIX/
*/
int main(int argc, char **argv)
{
int i;
for (i = 1; i < argc; i++)
{
for (int j = 0; j < 20; j++)
{
if (fork() == 0)
{
int rc = mkpath(argv[i], 0777);
if (rc != 0)
fprintf(stderr, "%d: failed to create (%d: %s): %s\n",
(int)getpid(), errno, strerror(errno), argv[i]);
exit(rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
}
int status;
int fail = 0;
while (wait(&status) != -1)
{
if (WEXITSTATUS(status) != 0)
fail = 1;
}
if (fail == 0)
printf("created: %s\n", argv[i]);
}
return(0);
}
#endif /* TEST */
ম্যাক্রো STRDUP()এবং FREE()ত্রুটির-পরীক্ষণের সংস্করণ
strdup()এবং free(), ঘোষণা emalloc.h(এবং বাস্তবায়িত মধ্যে
emalloc.cএবং estrdup.c)। "sysstat.h"এর ভাঙ্গা সংস্করণের সাথে হেডার পুলিশ <sys/stat.h>
এবং দ্বারা প্রতিস্থাপিত হতে পারে <sys/stat.h>আধুনিক ইউনিক্স সিস্টেমে (কিন্তু অনেক বিষয় 1990 সালে ব্যাক ছিল)। এবং "mkpath.h"ঘোষণা mkpath()।
V1.12 (উত্তর আসল সংস্করণটি) এবং v1.13 (উত্তর সংশোধিত সংস্করণ) মধ্যে পরিবর্তনের জন্য পরীক্ষা ছিল EEXISTমধ্যে
do_mkdir()। এটি সুইচ দ্বারা প্রয়োজনীয় হিসাবে চিহ্নিত করা হয়েছিল
- ধন্যবাদ, সুইচ। পরীক্ষার কোডটি একটি ম্যাকবুক প্রো (2.3GHz ইন্টেল কোর আই 7, ম্যাক ওএস এক্স 10.7.4 চলমান) তে সমস্যাটি পুনর্বিবেচনা এবং পুনরুত্পাদন করা হয়েছে এবং পরামর্শ দেয় যে সমস্যাটি পুনর্বিবেচনায় স্থির করা হয়েছে (তবে পরীক্ষার ফলে কেবল বাগের উপস্থিতি দেখাতে পারে , কখনও তাদের অনুপস্থিতি)। প্রদর্শিত কোডটি এখন v1.16; v1.13 সাল থেকে কসমেটিক বা প্রশাসনিক পরিবর্তন হয়েছে (যেমন mkpath.hপরিবর্তে ব্যবহার হিসাবে jlss.hএবং <unistd.h>কেবলমাত্র পরীক্ষার কোডে নিঃশর্তভাবে অন্তর্ভুক্ত )। এটি যুক্তিযুক্ত যুক্তিসঙ্গত যেটি যদি আপনার অস্বাভাবিকভাবে পুনরুদ্ধারের ব্যবস্থা না "sysstat.h"করে <sys/stat.h>তবে এটি দ্বারা প্রতিস্থাপন করা উচিত
।
(আপনাকে এট্রিবিউশন সহ যে কোনও উদ্দেশ্যে এই কোডটি ব্যবহার করার অনুমতি দেওয়া হয়েছে))
এই কোডটি গিটহাবের আমার এসওকিউ
(স্ট্যাক ওভারফ্লো প্রশ্নগুলি) সংগ্রহস্থলগুলিতে ফাইল হিসাবে mkpath.cএবং
এসসিআর / so-0067-5039
উপ-ডিরেক্টরিতে mkpath.h(ইত্যাদি)
উপলভ্য ।
if (errno != EEXIST) { status = -1; }যখন mkdir, ব্যর্থ।
stat()আগে ব্যবহারে এটাই সমস্যা mkdir(); এটি একটি টেকটিউ (চেকের সময়, ব্যবহারের সময়) সমস্যা। আমি একই 29-এলিমেন্ট পাথ তৈরি করতে ব্যাকগ্রাউন্ডে 13 টি প্রক্রিয়া চালিত শেল স্ক্রিপ্টের সাথে বাগটি টিকল করার চেষ্টা করেছি, এবং এটি আঘাত করতে পরিচালনা করি না। তারপরে আমি পরীক্ষার প্রোগ্রামটি কাঁটাচামচ করতে 20 বার হ্যাক করেছি এবং প্রতিটি বাচ্চাকে চেষ্টা করার চেষ্টা করেছি এবং এটি বাগটিতে আঘাত করতে সক্ষম হয়েছিল। ফিক্সড কোড থাকবে if (mkdir(path, mode) != 0 && errno != EEXIST) status = -1;। এটি বাগ প্রদর্শন করে না।
jlss.h, শিরোনাম ( , emalloc.h)। তবে, কোড আমার পাওয়া যায় SOQ সংগ্রহস্থলের GitHub থেকে ফাইল হিসেবে (স্ট্যাক ওভারফ্লো প্রশ্নাবলি) jlss.h, emalloc.cএবং emalloc.hমধ্যে src / libsoq উপ-নির্দেশিকা। আপনি প্রয়োজন হবে posixver.hখুব, এবং অন্য কয়েকজন ( debug.h, stderr.c, stderr.h- আমি মনে করে যে এটি, কিন্তু তুমি কি সব যে ডিরেক্টরির মধ্যে হওয়া উচিত প্রয়োজন)।
বুস্ট.ফায়ার সিস্টেমের সাহায্যে সহজ: create_directories
#include <boost/filesystem.hpp>
//...
boost::filesystem::create_directories("/tmp/a/b/c");
রিটার্নস: trueযদি কোনও নতুন ডিরেক্টরি তৈরি করা হয়, অন্যথায় false।
The <filesystem> header is not part of C++11; it is a proposal for C++ TR2 based on the Boost.Filesystem library. Visual C++ 2012 includes an implementation of the proposed library.
system("mkdir -p /tmp/a/b/c")
আমি ভাবতে পারি সবচেয়ে সংক্ষিপ্ততম উপায় (কোডের দৈর্ঘ্যের দিক থেকে, কার্যকরভাবে কার্যকর করার সময় নয়)।
এটি ক্রস প্ল্যাটফর্ম নয় তবে লিনাক্সের আওতায় কাজ করবে।
#include <sys/types.h>
#include <sys/stat.h>
int status;
...
status = mkdir("/tmp/a/b/c", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
থেকে এখানে । সি এপি-তে -p পতাকার সমতুল্য না থাকায় আপনাকে / tmp, / tmp / a, / tmp / a / b / এবং তারপরে / tmp / a / b / c এর জন্য পৃথক mkdirs করতে হতে পারে। আপনি যখন উচ্চ স্তরের কাজটি করছেন তখন নিশ্চিত হন এবং EEXISS এর ভুলটি উপেক্ষা করুন।
("/tmp/",...), ("/tmp/a/",...), ("/tmp/a/b/",...),("/tmp/a/b/c/",...)
এখানে কোডের আমার উদাহরণ (এটি উইন্ডোজ এবং লিনাক্স উভয়ের জন্যই কার্যকর):
#include <iostream>
#include <string>
#include <sys/stat.h> // stat
#include <errno.h> // errno, ENOENT, EEXIST
#if defined(_WIN32)
#include <direct.h> // _mkdir
#endif
bool isDirExist(const std::string& path)
{
#if defined(_WIN32)
struct _stat info;
if (_stat(path.c_str(), &info) != 0)
{
return false;
}
return (info.st_mode & _S_IFDIR) != 0;
#else
struct stat info;
if (stat(path.c_str(), &info) != 0)
{
return false;
}
return (info.st_mode & S_IFDIR) != 0;
#endif
}
bool makePath(const std::string& path)
{
#if defined(_WIN32)
int ret = _mkdir(path.c_str());
#else
mode_t mode = 0755;
int ret = mkdir(path.c_str(), mode);
#endif
if (ret == 0)
return true;
switch (errno)
{
case ENOENT:
// parent didn't exist, try to create it
{
int pos = path.find_last_of('/');
if (pos == std::string::npos)
#if defined(_WIN32)
pos = path.find_last_of('\\');
if (pos == std::string::npos)
#endif
return false;
if (!makePath( path.substr(0, pos) ))
return false;
}
// now, try to create again
#if defined(_WIN32)
return 0 == _mkdir(path.c_str());
#else
return 0 == mkdir(path.c_str(), mode);
#endif
case EEXIST:
// done!
return isDirExist(path);
default:
return false;
}
}
int main(int argc, char* ARGV[])
{
for (int i=1; i<argc; i++)
{
std::cout << "creating " << ARGV[i] << " ... " << (makePath(ARGV[i]) ? "OK" : "failed") << std::endl;
}
return 0;
}
ব্যবহার:
$ makePath 1/2 folderA/folderB/folderC
creating 1/2 ... OK
creating folderA/folderB/folderC ... OK
stat(সম্পর্কিত __STDC__) "সামঞ্জস্যের জন্য নন-এএনএসআই নাম রয়েছে" ।
এটি লক্ষ করা উচিত যে সি ++ 17 ফাইল সিস্টেম ইন্টারফেস থেকে শুরু করা স্ট্যান্ডার্ড লাইব্রেরির অংশ। এর অর্থ হ'ল ডিরেক্টরি তৈরি করতে কারও কাছে নিম্নলিখিত থাকতে পারে:
#include <filesystem>
std::filesystem::create_directories("/a/b/c/d")
এখানে আরও তথ্য: https://en.cppreferences.com/w/cpp/filesystem/create_directory
অতিরিক্তভাবে, জিসিসি সহ, সিএফএলজিএসে একজনকে "-std = c ++ 17" দরকার। এবং "-lstdc ++ fs" এলডিআইবিএস-এ। পরবর্তী সম্ভাব্য ভবিষ্যতে প্রয়োজন হবে না।
এটি আগের মতই তবে পুনরাবৃত্তির পিছনে পিছনে স্ট্রিংয়ের মাধ্যমে এগিয়ে কাজ করে। শেষ ব্যর্থতার জন্য সঠিক মান দিয়ে ভুল করে। যদি শীর্ষস্থানীয় স্ল্যাশ থাকে তবে লুপের বাইরে অতিরিক্ত সময় থাকতে পারে যা লুপের বাইরের একটি ফাইন্ড_ফর্স্ট_ফ () এর মাধ্যমে বা অগ্রণী / এবং প্রাক সেট 1 নির্ধারণের মাধ্যমে এড়ানো যেত The দক্ষতা একই হয় আমরা কোনও দ্বারা সেট আপ হয়ে যাই কিনা প্রাক লুপ কলটি ব্যবহার করার সময় প্রথম লুপ বা প্রাক লুপ কল এবং জটিলতাটি কিছুটা বেশি (সামান্য) বেশি হবে।
#include <iostream>
#include <string>
#include <sys/stat.h>
int
mkpath(std::string s,mode_t mode)
{
size_t pos=0;
std::string dir;
int mdret;
if(s[s.size()-1]!='/'){
// force trailing / so we can handle everything in loop
s+='/';
}
while((pos=s.find_first_of('/',pos))!=std::string::npos){
dir=s.substr(0,pos++);
if(dir.size()==0) continue; // if leading / first time is 0 length
if((mdret=mkdir(dir.c_str(),mode)) && errno!=EEXIST){
return mdret;
}
}
return mdret;
}
int main()
{
int mkdirretval;
mkdirretval=mkpath("./foo/bar",0755);
std::cout << mkdirretval << '\n';
}
আপনি "সি ++" বলেছেন তবে এখানকার প্রত্যেকে "বাশ শেল" ভাবছেন বলে মনে হচ্ছে।
Gnu- তে সোর্স কোডটি দেখুন mkdir; তারপরে আপনি দেখতে পারবেন কীভাবে সি ++ এ শেল কমান্ডগুলি প্রয়োগ করা যায়।
bool mkpath( std::string path )
{
bool bSuccess = false;
int nRC = ::mkdir( path.c_str(), 0775 );
if( nRC == -1 )
{
switch( errno )
{
case ENOENT:
//parent didn't exist, try to create it
if( mkpath( path.substr(0, path.find_last_of('/')) ) )
//Now, try to create again.
bSuccess = 0 == ::mkdir( path.c_str(), 0775 );
else
bSuccess = false;
break;
case EEXIST:
//Done!
bSuccess = true;
break;
default:
bSuccess = false;
break;
}
}
else
bSuccess = true;
return bSuccess;
}
সুতরাং আমার mkdirp()আজকের দরকার , এবং এই পৃষ্ঠায় সমাধানগুলি অতি জটিল found অতএব আমি একটি মোটামুটি ছোট স্নিপেট লিখেছি, যা সহজেই অন্যদের জন্য অনুলিপি করা যায় যারা এই থ্রেডটিতে হোঁচট খায় তারা আশ্চর্য হয় যে কেন আমাদের এত লাইন কোডের প্রয়োজন।
mkdirp.h
#ifndef MKDIRP_H
#define MKDIRP_H
#include <sys/stat.h>
#define DEFAULT_MODE S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH
/** Utility function to create directory tree */
bool mkdirp(const char* path, mode_t mode = DEFAULT_MODE);
#endif // MKDIRP_H
mkdirp.cpp
#include <errno.h>
bool mkdirp(const char* path, mode_t mode) {
// const cast for hack
char* p = const_cast<char*>(path);
// Do mkdir for each slash until end of string or error
while (*p != '\0') {
// Skip first character
p++;
// Find first slash or end
while(*p != '\0' && *p != '/') p++;
// Remember value from p
char v = *p;
// Write end of string at p
*p = '\0';
// Create folder from path to '\0' inserted at p
if(mkdir(path, mode) == -1 && errno != EEXIST) {
*p = v;
return false;
}
// Restore path to it's former glory
*p = v;
}
return true;
}
আপনি যদি কনট কাস্টিং এবং অস্থায়ীভাবে স্ট্রিংটি সংশোধন করতে পছন্দ করেন না তবে কেবল একটি করুন strdup()এবং free()এটি পরে করুন।
যেহেতু এই পোস্টটি "ডিরেক্টরী ট্রি ট্রি তৈরি করুন" এর জন্য গুগলে উচ্চ স্থান অর্জন করছে, তাই আমি একটি উত্তর পোস্ট করতে যাচ্ছি যা উইন্ডোজের পক্ষে কাজ করবে - এটি ইউনিকোডি বা এমবিসিএসের জন্য সংকলিত উইন 32 এপিআই ব্যবহার করে কাজ করবে। এটি উপরের মার্কের কোড থেকে পোর্ট করা আছে।
যেহেতু এটি উইন্ডোজ যার সাথে আমরা কাজ করছি, ডিরেক্টরি বিভাজকগুলি হ'ল ব্যাক-স্ল্যাশ, ফরোয়ার্ড স্ল্যাশ নয়। আপনি যদি না বরং ফরোয়ার্ড স্ল্যাশ করতে চান তবে পরিবর্তন '\\'করুন'/'
এটি এর সাথে কাজ করবে:
c:\foo\bar\hello\world
এবং
c:\foo\bar\hellp\world\
(যেমন: পিছনে স্ল্যাশ লাগবে না, সুতরাং আপনার এটি পরীক্ষা করতে হবে না))
" উইন্ডোজে কেবলমাত্র SHCreateDirectoryEx () ব্যবহার করুন" বলার আগে নোট করুন যে SHCreateDirectoryEx () অবচিত এবং উইন্ডোজের ভবিষ্যতের সংস্করণগুলি থেকে যে কোনও সময় অপসারণ করা যেতে পারে।
bool CreateDirectoryTree(LPCTSTR szPathTree, LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL){
bool bSuccess = false;
const BOOL bCD = CreateDirectory(szPathTree, lpSecurityAttributes);
DWORD dwLastError = 0;
if(!bCD){
dwLastError = GetLastError();
}else{
return true;
}
switch(dwLastError){
case ERROR_ALREADY_EXISTS:
bSuccess = true;
break;
case ERROR_PATH_NOT_FOUND:
{
TCHAR szPrev[MAX_PATH] = {0};
LPCTSTR szLast = _tcsrchr(szPathTree,'\\');
_tcsnccpy(szPrev,szPathTree,(int)(szLast-szPathTree));
if(CreateDirectoryTree(szPrev,lpSecurityAttributes)){
bSuccess = CreateDirectory(szPathTree,lpSecurityAttributes)!=0;
if(!bSuccess){
bSuccess = (GetLastError()==ERROR_ALREADY_EXISTS);
}
}else{
bSuccess = false;
}
}
break;
default:
bSuccess = false;
break;
}
return bSuccess;
}
c:\this\is\a/mixed/path\of\slashesসাধারণত উইন্ডোজ স্ল্যাশগুলি ব্যাকস্ল্যাশ হয়। যা হওয়া উচিত তা হ'ল কলারের পথটি স্যানিটাইজ করা উচিত এবং নিশ্চিত করা উচিত যে এই পদ্ধতিটি কল করার আগে সমস্ত স্ল্যাশগুলি যথাযথ।
আমি জানি এটি একটি পুরানো প্রশ্ন তবে এটি গুগল অনুসন্ধানের ফলাফলগুলিতে উচ্চ দেখায় এবং এখানে প্রদত্ত উত্তরগুলি সত্যিই সি ++ এ নয় বা কিছুটা জটিলও।
দয়া করে নোট করুন যে আমার উদাহরণে createDirTree () খুব সহজ কারণ সমস্ত ভারী উত্তোলন (ত্রুটি পরীক্ষা করা, পাথের বৈধতা) যেভাবেই হোক createDir () দ্বারা করা দরকার। ডিরেক্টরী ইতিমধ্যে উপস্থিত থাকলে বা পুরো জিনিসটি কাজ না করে তবে createDir () এর সত্য হওয়া উচিত।
আমি এখানে সি ++ তে কীভাবে করব:
#include <iostream>
#include <string>
bool createDir(const std::string dir)
{
std::cout << "Make sure dir is a valid path, it does not exist and create it: "
<< dir << std::endl;
return true;
}
bool createDirTree(const std::string full_path)
{
size_t pos = 0;
bool ret_val = true;
while(ret_val == true && pos != std::string::npos)
{
pos = full_path.find('/', pos + 1);
ret_val = createDir(full_path.substr(0, pos));
}
return ret_val;
}
int main()
{
createDirTree("/tmp/a/b/c");
return 0;
}
অবশ্যই ক্রিয়েডির () ফাংশনটি সিস্টেম-নির্দিষ্ট হবে এবং অন্যান্য উত্তরগুলিতে এটি ইতিমধ্যে লিনাক্সের জন্য কীভাবে লিখতে হবে তার যথেষ্ট উদাহরণ রয়েছে, তাই আমি এড়িয়ে যাওয়ার সিদ্ধান্ত নিয়েছি।
এখানে অনেকগুলি পদ্ধতির বর্ণনা দেওয়া হয়েছে তবে তাদের বেশিরভাগেরই আপনার কোডটিতে আপনার পথের কঠোর কোডিং দরকার। এই সমস্যার জন্য একটি সহজ সমাধান রয়েছে, কিউডিআর এবং কিফিলআইএনফো, দুটি শ্রেণির কিউটি ফ্রেমওয়ার্ক ব্যবহার করে। আপনার ইতিমধ্যে লিনাক্স পরিবেশে Qt ব্যবহার করা সহজ হওয়া উচিত।
QString qStringFileName("path/to/the/file/that/dont/exist.txt");
QDir dir = QFileInfo(qStringFileName).dir();
if(!dir.exists()) {
dir.mkpath(dir.path());
}
নিশ্চিত হয়ে নিন যে সেই পথে আপনার লেখার অ্যাক্সেস রয়েছে।
এখানে সি / সি ++ রিকर्सিভ ফাংশন যা dirname()নীচের দিকের ডিরেক্টরি ট্রিটিকে অনুসরণ করতে ব্যবহার করে । এটি কোনও বিদ্যমান পূর্বপুরুষকে খুঁজে পাওয়ার সাথে সাথে এটি বন্ধ হয়ে যাবে।
#include <libgen.h>
#include <string.h>
int create_dir_tree_recursive(const char *path, const mode_t mode)
{
if (strcmp(path, "/") == 0) // No need of checking if we are at root.
return 0;
// Check whether this dir exists or not.
struct stat st;
if (stat(path, &st) != 0 || !S_ISDIR(st.st_mode))
{
// Check and create parent dir tree first.
char *path2 = strdup(path);
char *parent_dir_path = dirname(path2);
if (create_dir_tree_recursive(parent_dir_path, mode) == -1)
return -1;
// Create this dir.
if (mkdir(path, mode) == -1)
return -1;
}
return 0;
}
অন্যরা আপনাকে সঠিক উত্তরটি পেয়েছে তবে আমি ভেবেছিলাম যে আপনি করতে পারেন এমন আরও একটি পরিষ্কার জিনিস আমি প্রদর্শন করব:
mkdir -p /tmp/a/{b,c}/d
নিম্নলিখিত পাথ তৈরি করবে:
/tmp/a/b/d
/tmp/a/c/d
ধনুর্বন্ধনী আপনাকে স্তরের স্তরের একই স্তরে একবারে একাধিক ডিরেক্টরি তৈরি করতে দেয়, অন্যদিকে -pবিকল্পটির অর্থ "প্রয়োজনীয় হিসাবে পিতামাত ডিরেক্টরিগুলি তৈরি করা"।