I was trying to create folders named 1 2 3 4, using the C++ program below. I can successfully achieve that in RHEL.
However it created a folder named {1..4} in ubuntu 13.10.
Why does this happen? Thank you for helping me!
#include <cstdlib>
int main()
{
std::system("mkdir {1..4}");
}
It's a part of CPP unit test in our product. Yes, it's ugly. But I am afraid very few thing can be done in this situation.
You are right.
In RHEL,
sh -c 'echo {1..4}'
1 2 3 4
In Ubuntu
sh -c 'echo {1..4}'
{1..4}
So I use the program below instead. It works!
#include
int main()
{
std::system("bash -c 'mkdir {1..4}'");
}
seems system use sh by default....Thank you for your answer!
A bit of terminology: Linux has directories in its file systems, not "folders" (folders may appear visually on the desktop, but that is a desktop detail).
You don't need to use system(3) (which is running sh
not bash
!).
And POSIX sh
don't know the {1..4}
notation, hence the {1..4}
string is passed verbatim to /bin/mkdir
command (see mkdir(1) ...).
Run
sh -c 'echo {1..4}'
to test that sh
don't understand the {1..4}
notation.
(so it is a bug in your old RHEL, where perhaps /bin/sh
is a symlink to /bin/bash
while on Debian and Ubuntu it is a symlink to the more Posix compliant and faster /bin/dash
)
Just use the mkdir(2) syscall and code
#include <cstdlib>
#include <cstdio>
#include <sys/stat.h>
#include <sys/types.h>
int main() {
for (int i=1; i<=4; i++) {
char buf[8];
snprintf(buf, sizeof(buf), "%d", i);
if (mkdir(buf, 0755))
{ perror("mkdir"); exit(EXIT_FAILURE); };
}
}
I hope you don't want to create a single directory named 1 2 3 4
. It is possible and easy, but it really is poor taste. For your mental safety, use only letters, digits and underscores _
in directory names.
I am using snprintf(3) to convert an int to a character buffer. With C++11 you could use std::to_string and c_str ...
Read Advanced Linux Programming...
Using the mkdir(2)
syscall instead of going thru a command invoked by system(3)
has several important advantages:
- it is much faster, you don't need to fork(2) a
/bin/sh -c
shell like system(3)
should do.
- it uses much less resources, since no additional process is
fork
-ed, so your program will still run when you have reached your limits (see setrlimit(2) ...)
- it is more reliable. Should
mkdir(2)
fail you could (and should) handle the failure nicely. See errno(3) and strerror(3) ....