C ++ / Linuxでディレクトリツリーを作成するにはどうすればよいですか?


109

C ++ / Linuxで複数のディレクトリを簡単に作成する方法が欲しい。

たとえば、次のディレクトリにファイルlola.fileを保存します。

/tmp/a/b/c

しかし、ディレクトリが存在しない場合は、自動的に作成する必要があります。実用的な例は完璧でしょう。


C ++には、ディレクトリとツリー自体を作成するための組み込み機能はありません。Cとシステムコール、またはBoostなどの外部ライブラリを使用する必要があります。Cおよびシステムコールはプラットフォームに依存します。
jww 2014年

6
@noloaderどうもありがとうございました。しかし、4年後、13の異なる方法でうなり声を見ることができるので、ほとんど答えが出たと思います...
Lipis

ええ、私はC ++でそれを行うことができないと明示的に誰も述べていないことに驚いていました(Linuxで動作するC ++のポータブルメソッドが必要だと仮定した場合)。しかし、あなたはおそらくそれを知っていました;)。ただし、移植性のないCコードについては多くの良い提案がありました。
jww 2014年

「C ++ / Linux」とは何ですか?
オービットの軽量レース、2015

3
@LightnessRacesinOrbit LinuxでのC ++の私の大学年です:)
Lipis

回答:


59

C ++ 17以降で は、最新のC ++プログラムで使用する必要がある<filesystem>関数付きの標準ヘッダーがあります std::filesystem::create_directories。ただし、C ++標準関数には、POSIX固有の明示的なアクセス許可(モード)引数はありません。

ただし、C ++コンパイラでコンパイルできるC関数を次に示します。

/*
@(#)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.cestrdup.c)。"sysstat.h"壊れたのバージョンと、ヘッダのお得な情報<sys/stat.h> と置き換えることができ<sys/stat.h>、現代のUnixシステムで(しかし、多くの問題が戻って1990年にありました)。と"mkpath.h"宣言しmkpath()ます。

V1.12(答えの元のバージョン)とV1.13(回答の修正版)との間の変化のための試験であっEEXISTにおける do_mkdir()。これはスイッチによって必要に応じて指摘されました —ありがとう、スイッチ。テストコードがアップグレードされ、MacBook Pro(2.3GHz Intel Core i7、Mac OS X 10.7.4を実行)で問題が再現され、リビジョンで問題が修正されることが示唆されています(ただし、テストではバグの存在のみを示すことができます) 、彼らの不在は決してありません)。ここに示すコードはv1.16です。v1.13以降に表面的な変更または管理上の変更が行われています(mkpath.h代わりに使用jlss.hし、<unistd.h>無条件にテストコードにのみ含めるなど)。あなたが異常に扱いにくいシステムを持っているのでない限り、これを"sysstat.h"置き換えるべきだと 主張するのは理にかなって<sys/stat.h>います。

(これにより、このコードを帰属表示のある目的に使用する許可が与えられます。)

このコードは 、GitHubの私のSOQ(Stack Overflow Questions)リポジトリでファイルとして(mkpath.cおよび mkpath.hその他) src / so-0067-5039 サブディレクトリにあります。


2
確かにシステムより速いです。システムには多くのオーバーヘッドが関係しています。基本的に、プロセスをフォークする必要があります。次に、少なくとも2つのバイナリをロードする必要があります(おそらく1つはすでにキャッシュにあります)。その上に、もう1つのフォークが
追加され

1
私は忘れました:そして、 "mkdir -p"は少なくとも上記のコードと同じことをします!
ypnos 2009年

7
このコードには、実際にヒットした微妙な競合状態があります。複数のプログラムが同時に起動し、同じフォルダパスを作成した場合にのみ発生します。修正はif (errno != EEXIST) { status = -1; }、mkdirが失敗したときに追加することです。
2012

2
@スイッチ:ありがとう。これはstat()beforeの使用に関する問題mkdir()です。TOCTOU(チェック時、使用時)の問題です。同じ29要素のパスを作成する13のプロセスをバックグラウンドで実行するシェルスクリプトでバグをくすぐろうとしましたが、うまくいきませんでした。次に、テストプログラムをハッキングして20回フォークし、それぞれの子供に試してもらいましたが、なんとかバグにぶつかりました。修正されたコードにはがありif (mkdir(path, mode) != 0 && errno != EEXIST) status = -1;ます。それはバグを示していません。
ジョナサンレフラー

2
@DavidMerinos:それらはライブラリではなくヘッダー(jlss.hemalloc.h)です。ただし、コードは私の中で提供されていますSOQファイルとしてGitHubの上(スタックオーバーフローの質問)リポジトリjlss.hemalloc.cおよびemalloc.hのsrc / libsoqサブディレクトリ。あなたが必要になりますposixver.hあまりにも、そして他のいくつか(debug.hstderr.cstderr.h-私はそれはそれだと思うが、何が必要、すべてそのディレクトリにする必要があります)。
ジョナサンレフラー

157

Boost.Filesystemで簡単: create_directories

#include <boost/filesystem.hpp>
//...
boost::filesystem::create_directories("/tmp/a/b/c");

戻り値:true新しいディレクトリが作成された場合、それ以外の場合false


9
まあ、ほとんどのboostライブラリはヘッダーのみです。つまり、使用するもの以外にオーバーヘッドはありません。ただし、Boost.Filesystemの場合は、コンパイルが必要です。私のディスクでは、コンパイルされたライブラリの重さは約60KBです。
–Benoît

1
@Lipis:組み込みシステムを正確に教えてください。ほとんどすべてのLinuxディストリビューションで利用できるはずです。
–Benoît

4
@danijarによって言及されたC ++ 11コンパイラに関して、ここのコメントはそれをより明確にしました: 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.
Chunliang Lyu

5
ブースト::ファイルシステムがない、ヘッダーのみです:stackoverflow.com/questions/13604090/...
ftvs

2
私見:何か重要なことを行い、時の試練に耐えることを意図している私のプロジェクトでは、ブーストとしてそのような信じられないほど有用で強力な標準化されたツールのセットを持っていることはコンパイルする価値があります。その多くはすでに標準C ++に組み込まれていますが、今後さらに増える予定です。試してみて、それに固執してください。ささいな以上のニーズがあり、ホイールを再発明したくない場合は、メリットがあります。:-)
moodboom 2016

42
system("mkdir -p /tmp/a/b/c")

私が考えることができる最も短い方法です(コードの長さに関しては、必ずしも実行時間ではありません)。

クロスプラットフォームではありませんが、Linuxで動作します。


1
シェルコマンドとしてソリューションを提供する場合は、system(3)
dmckee --- ex-moderator kitten

26
#include <sys/types.h>
#include <sys/stat.h>

int status;
...
status = mkdir("/tmp/a/b/c", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);

ここから。C APIには-pフラグに相当するものがないため、/ tmp、/ tmp / a、/ tmp / a / b /、次に/ tmp / a / b / cに対して個別のmkdirを実行する必要がある場合があります。上位レベルのものを実行している間は、必ずEEXISTS errnoを無視してください。


面白い事実:少なくともSolarisとHP / UXにはmkdirp()がありますが、移植性には明らかに最適ではありません。
マーティンカーペンター、

それがポイントです。これらすべての関数を個別に呼び出したくないのです。
リピス

mkdirを数回呼び出すと、システムを1回呼び出すよりも高速になります。
ポールトンブリン

私はあなたが提案していることを理解していません:異なる引数でmkdirを4回呼び出す?("/tmp/",...)("/tmp/a/",...)("/tmp/a/b/",...)("/tmp/a/b/c/",...)
アントニオ

1
繰り返しますが、同じ呼び出しを3回行うのはかなり簡単です。重要なのは、コードを記述できるようにするためではなく、コードを記述できる十分な情報を提供することです。
Paul Tomblin

25

これが私のコード例です(WindowsとLinuxの両方で機能します)。

#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

そのコメントの2番目です。ディレクトリを作成する移植可能なC ++の方法を見つけることは、(驚くべきことに)簡単な作業ではありません。この回答にはもっと賛成票が必要です。
Manuel Lafond

1
Windowsでは、末尾の文字がバックスラッシュの場合、isDirExistは機能しません。常にfalseを返します。コードを次のように変更する必要があります。std :: string dirPath(path); while( '\\' == * dirPath.rbegin())dirPath.pop_back(); ...そして、もちろん、_statの呼び出しでdirPath.c_str()を渡します。
MiloDC 2017

Windows APIには、プリコンパイラテストの必要がないstat(に関連する__STDC__)「互換性のための非ANSI名」があります。
サンドバーグ

18

C ++ 17ファイルシステムインターフェイスからの開始は標準ライブラリの一部であることに注意してください。これは、ディレクトリを作成するために以下を実行できることを意味します。

#include <filesystem>

std::filesystem::create_directories("/a/b/c/d")

詳細はこちら:https : //en.cppreference.com/w/cpp/filesystem/create_directory

さらに、gccでは、CFLAGSに「-std = c ++ 17」を実行する必要があります。そして、 "-lstdc ++ fs"をLDLIBSに。後者は潜在的に将来必要とされないでしょう。


新しい十分なVisual C ++と「/ std:c ++ latest」でも動作するはずです。参照:blogs.msdn.microsoft.com/vcblog/2018/05/07/...developercommunity.visualstudio.com/content/problem/296680/...
ロン・バーク

9

これは前のものと似ていますが、再帰的に後方にではなく、文字列を前方に向かって機能します。最後の失敗の正しい値をerrnoに残します。先頭にスラッシュがある場合、ループの外側にあるfind_first_of()を介して、または先頭の/を検出してpreを1に設定することで回避できたはずの余分な時間があります。効率は、最初のループまたはループ前の呼び出し。ループ前の呼び出しを使用すると、複雑さが(わずかに)高くなります。

#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';

}

7

あなたは「C ++」と言いましたが、ここの誰もが「Bashシェル」を考えているようです。

ソースコードをgnuにチェックアウトしてくださいmkdir。その後、C ++でシェルコマンドを実装する方法を確認できます。


さて、system( "mkdir ...")はLinuxでうまくいくはずです。ただし、クロスプラットフォームではありません。
ChristopheD

@MartinCarpenterの2番目のコメント
Joshua Hedges

6
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;
}

それは私にとって最高の解決策です!ありがとう)))!
ネオ

多分それはダンプの質問ですが、mkdirの前の「::」プレフィックスは何ですか?
Rayee Roded

1
答えが見つかりました
:::

4

だから私はmkdirp()今日必要であり、このページの解決策は非常に複雑であることがわかりました。したがって、私はかなり短いスニペットを書きました。このスレッドにつまずく他の人に簡単にコピーして、なぜこれほど多くのコード行が必要なのか不思議に思います。

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;
}

constキャストや文字列の一時的な変更が気に入らない場合は、あとでa strdup()を実行してくださいfree()


要旨にも投稿されているので、次回必要になったときにどこに置いたか忘れないでください:) gist.github.com/jonasfj/7797272
jonasfj

2
定数として渡される文字列を変更しようとするのは悪いことです。それ以外は、文字列リテラルが渡されると、劇的な失敗につながる可能性があります。
Jonathan Leffler、2015年

2
完全に正しい....これは実際に悪いです...おそらくstrcpyはこれをより良くするでしょう...
jonasfj

3

この投稿はGoogleで「ディレクトリツリーの作成」で上位にランクされているため、Windowsで機能する回答を投稿します。これは、UNICODEまたはMBCS用にコンパイルされたWin32 APIを使用して機能します。これは、上記のMarkのコードから移植されたものです。

これは作業中のWindowsであるため、ディレクトリの区切り文字はバックスラッシュであり、スラッシュではありません。スラッシュを使用したい場合は、次のように変更'\\'します'/'

それは動作します:

c:\foo\bar\hello\world

そして

c:\foo\bar\hellp\world\

(つまり、末尾のスラッシュは必要ないので、チェックする必要はありません。)

「WindowsでSHCreateDirectoryEx()を使用する」と言う前に、SHCreateDirectoryEx()は非推奨であり、Windowsの将来のバージョンからいつでも削除される可能性があることに注意してください。

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;
}

1つの小さなmod-パスにバックスラッシュが含まれている場合、これは機能しません。ここに: `LPCTSTR szLast = _tcsrchr(szPathTree、 '\\');`これを追加するだけです: `` `if(nullptr == szLast){szLast = _tcsrchr(szPathTree、 '/'); } `` `
Den-Jason

1
情報をありがとう。パスが混在している場合はどうなりますか?つまり、c:\this\is\a/mixed/path\of\slashes通常、Windowsのスラッシュはバックスラッシュです。何が起こるかは、このメソッドを呼び出す前に、呼び出し側がパスをサニタイズし、すべてのスラッシュが適切であることを確認する必要があります。
アンディ

3

私はそれが古い質問であることを知っていますが、それはグーグルの検索結果に高く表示され、ここで提供される回答は実際にはC ++ではないか、少し複雑すぎます。

いずれにしても、面倒な作業(エラーチェック、パス検証)はすべてcreateDir()で実行する必要があるため、私の例ではcreateDirTree()は非常に単純です。また、ディレクトリがすでに存在する場合、またはすべてが機能しない場合、createDir()はtrueを返す必要があります。

C ++でこれを行う方法は次のとおりです。

#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;
}

もちろんcreateDir()関数はシステム固有であり、他の回答にはLinuxでの記述方法の例がすでに十分あるため、スキップすることにしました。


1

dirが存在しない場合は作成します。

boost::filesystem::create_directories(boost::filesystem::path(output_file).parent_path().string().c_str()); 

1

ここでは多くのアプローチについて説明しましたが、それらのほとんどは、コードへのパスをハードコーディングする必要があります。QDirフレームワークの2つのクラスであるQDirとQFileInfoを使用して、その問題を簡単に解決できます。すでにLinux環境にいるので、Qtは使いやすいはずです。

QString qStringFileName("path/to/the/file/that/dont/exist.txt");
QDir dir = QFileInfo(qStringFileName).dir();
if(!dir.exists()) {
        dir.mkpath(dir.path());
}

そのパスへの書き込みアクセス権があることを確認してください。



0

以下dirname()は、ディレクトリツリーを下から上へトラバースするために使用するC / C ++再帰関数です。既存の祖先が見つかるとすぐに停止します。

#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;
}

-2

他の人はあなたに正しい答えを得ましたが、私はあなたができる別のきちんとしたことを示すと思いました:

mkdir -p /tmp/a/{b,c}/d

次のパスを作成します。

/tmp/a/b/d
/tmp/a/c/d

中括弧を使用すると、階層の同じレベルに一度に複数のディレクトリを作成できますが、-pオプションは「必要に応じて親ディレクトリを作成する」ことを意味します。


ポールの答えを見た後、私(そして他の多くの人々)が質問を誤解していることに
気づきました

誰かがsystem( "mkdir -p / tmp / a / {b、c} / d")に変更するだけでこれを更新できる場合、問題はシェルでの実行ではなく、C ++を介して実行することです。
リピス

{a、b}はsh派生シェルとcsh派生シェルの両方で機能すると思います。ただし、system()コマンドで機能するかどうかはわかりません。
ポールトンブリン

1
@Lipis:system()を介してそれを行うことは、OPの質問に対する良い解決策ではありません。@Andy:これまで考えたことはありませんでしたが、「mkdir -p」を「echo」に置き換えてテストしたところ、「/ tmp / a / b / d / tmp / a / c / d」と出力されました。これは、mkdirではなく、シェルがそれを実行していることを示唆しています。
rmeador 2009年

@rmeador:それが良い解決策ではない場合、他に提案することはありますか?私はそのシェルを介してそれを行う方法を..私の問題ではありませんC ++ ...てやりたい
Lipis
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.