1

I have variable "one" which contains following

avi,mkw,dvd,cd

im trying to dynamicly create directories that would look like this

type-avi
type-mkw
type-dvd
type-cd

I have tried to achieve wanted result with following code

mkdir type-{"$one"}

but instead of creating 4 directories , it created one directory called

type-{avi,mkw,dvd,cd}

I suppose this is wrong method.. if so , how can i create dynamicly directories with "suffixes" stored in variabe?

7
  • 1
    See stackoverflow.com/questions/4956584/… for why this didn't work. You get to loop manually for this. Commented Nov 16, 2015 at 16:35
  • indeed i could loop and just use the cut command to get the value , but how can i determine the length if the variable based on "," ? in my example avi,mkw,dvd,cd i would need to return 4 Commented Nov 16, 2015 at 16:45
  • mkdir type-{$one} works in ksh (ver 93+). Note, NO dbl-quotes on $one (One of the few times you don't want to quote a variable, so it seems ;-) ) . Good luck. Commented Nov 16, 2015 at 16:46
  • @shellter Does that work if the elements of $one have spaces in their names or other globs? Commented Nov 16, 2015 at 16:49
  • Hm... actually that's an interesting trade-off here. Brace expansion means you can correctly glob individual entries at expansion time but an array means you need to move that to globbing to creation time. Commented Nov 16, 2015 at 16:54

2 Answers 2

5

Use an array instead of your string variable for this.

IFS=, read -a onearr <<<"$one"
mkdir "${onearr[@]/#/type-}"

Or if you don't need the $one string in the first place just create the array manually.

onearr=(avi mkw dvd cd)
mkdir "${onearr[@]/#/type-}"

If you aren't worried about spaces or anything in the values in $one and can trust your input to be "safe" and not exploitative and can't use read then you could use this to create the array instead (but it is just flat out a worse soluton).

onearr=($(tr , ' ' <<<"$one"))
Sign up to request clarification or add additional context in comments.

11 Comments

if i had variable which would be one="avi,mkw,dvd,cd" how could i create array from it ? ...im not sure if this question is for new topic or not :)
The first snippet here does exactly that. Notice that is uses $one.
is there any way how to do it without read? Im doing this exercises in order to prepare for school and we are not allowed to use read
thanks! :) one ast quetion why is the order mkdir "${onearr[@]/#/type-}" reversed? and what does # in it mea?
See Shell Parameter Expansion in the bash manual.
|
0

A way to do this without reading into the shell, in a traditional tools pipeline approach:

echo "$one" |
tr ',' '\n' | 
sed "s/^/mkdir 'type-/; s/$/'/" |
sh -x

Your original attempt was very close. To make it work, you can use the shell eval command:

eval mkdir type-{$one}

or

echo mkdir type{"$one"} | bash

In either case, the effect causes bash to re-evaluate the line.

I personally would not recommend this approach for these reasons:

  1. eval can be a security risk and is little used, maintainers will have to do a double-take.
  2. Brace Expansion is a bash-type shell extension and while I love bash, I write all shell scripts to run with the POSIX /bin/sh.
  3. These will not handle unusual characters in filenames, such as spaces.

The eval causes the shell to re-evaluate the string after the variable substition has been performed. To gain more understanding on these topics, see "Brace Expansion" and also the eval command, both on the bash man page.

7 Comments

The final snippet is incorrect. You missed echo. And none of these will work with spaces in the contents of the components of $one. Not to mention that these all open up the potential for arbitrary code execution if you can't trust the value of $one.
@EtanReisner Typo, thanks, fixed. Problems with the last two examples? More reasons not to use them. Answer updated, thanks!
@EtanReisner In the first example, what happens when there are "spaces in the contents of the components of $one"? Did you try it?
Non-newline spaces in the first example are fine. Newlines break though. And it still allows for arbitrary code execution. Imagine one was foo'; touch /tmp/broken; : '?
@EtanReisner Non-newline spaces? Sounds like back pedaling to me. Why not say "newlines"? I understand what you mean by "arbitrary code execution." The likelihood of newlines and arbitrary code execution varies widely by the context within which the code is used.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.