Active1 year, 1 month ago
- Program For Loops In C
- How To Program For Loops In Mac Os Unix Based
- How To Program For Loops In Mac Os Unix Password
- How To Program For Loops In Mac Os Unix Commands
- How To Program For Loops In Mac Os Unix Certified
Mac OS X's Unix Development Tools The version of Unix that you'll encounter in Mac OS X's Terminal is similar to other versions you have seen, but dissimilar in some fundamental and often surprising ways. Nessus is supported by a variety of platforms including Windows 7 and 8, Mac OS X, and popular Linux distros like Debian, Ubuntu, Kali Linux etc. Read more here and download Nessus 7.
I have gotten the following to work:
It produces a bunch of lines of
output: 2
, output: 3
, so on.However, trying to run the following:
produces the following:
How can I get the compiler to realize it should treat $max as the other end of the array, and not part of a string?
Peter Mortensen14.4k1919 gold badges8888 silver badges117117 bronze badges
eykanaleykanal
16.7k1313 gold badges6868 silver badges103103 bronze badges
11 Answers
Brace expansion, {x..y} is performed before other expansions, so you cannot use that for variable length sequences.
Instead, use the
seq 2 $max
method as user mob stated.So, for your example it would be:
Peter Mortensen14.4k1919 gold badges8888 silver badges117117 bronze badges
whatsisnamewhatsisname4,64122 gold badges1616 silver badges2424 bronze badges
Try the arithmetic-expression version of
for
:This is available in most versions of bash, and should be Bourne shell (sh) compatible also.
system PAUSEsystem PAUSE26k1717 gold badges5656 silver badges5858 bronze badges
Step the loop manually:
If you don’t have to be totally POSIX, you can use the arithmetic for loop:
Or use jot(1) on BSD systems:
Nietzche-jouNietzche-jou12.3k44 gold badges2929 silver badges4242 bronze badges
ephemientephemient161k3232 gold badges236236 silver badges362362 bronze badges
If the
seq
command available on your system:If not, then use poor man's
seq
with perl
:Watch those quote marks.
mobmob102k1515 gold badges133133 silver badges252252 bronze badges
This is a way:
Bash:
Bash:
The above Bash way will work for
ksh
and zsh
too, when bash -c
is replaced with ksh -c
or zsh -c
respectively.Note:
JahidJahidfor i in {2..${max}}; do echo $i; done
works in zsh
and ksh
.14.6k55 gold badges6565 silver badges8787 bronze badges
rashedcsrashedcs
Here it worked on Mac OS X.
It includes the example of a BSD date, how to increment and decrement the date also:
Peter Mortensen14.4k1919 gold badges8888 silver badges117117 bronze badges
minhas23minhas236,77622 gold badges4747 silver badges3737 bronze badges
Well, as I didn't have the
seq
command installed on my system (Mac OS X v10.6.1 (Snow Leopard)), I ended up using a while
loop instead:*Shrugs* Whatever works.
Peter Mortensen14.4k1919 gold badges8888 silver badges117117 bronze badges
eykanaleykanal16.7k1313 gold badges6868 silver badges103103 bronze badges
These all do
{1..8}
and should all be POSIX. They also will not break if youput a conditional continue
in the loop. The canonical way:Another way:
and another:
user4427511
Use:
You need the explicit 'eval' call to reevaluate the {} after variable substitution.
Peter Mortensen14.4k1919 gold badges8888 silver badges117117 bronze badges
Chris DoddChris Dodd
protected by Brad Larson♦Nov 1 '13 at 17:19
Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?
Would you like to answer one of these unanswered questions instead?
Not the answer you're looking for? Browse other questions tagged unixsyntaxshell or ask your own question.
Active5 years, 6 months ago
I'm getting a bit confused on how to handle spaces in path names when returned in a for loop.
Rationale: I'm cleaning up the permissions on folders and files that I copy over from Windows. Most of the files end up with
-rwx------
or -rwxr-xr-x
permissions so I like to do 'chmod -x *
' and then 'chmod u+x <folders>
' so I'm trying the following:which works fine, as long as the directories don't have a space in the name.
I've tried different permutations of
chmod u+x '$i'
, chmod u+x '$i'
and similar to get the behavior I wanted, but to no avail.How to improve my bash code, that works with folder names containing space?
The purpose of this is to be able to remove the 'exec' bit from plain files (hence the
bmike♦chmod -x *
part) but then to restore it to the directories to allow getting into them (chmod u+x <dirname>
). From the comments and answers so far I'm thinking that it probably will be easier to do with the proper 'find' incantation168k4646 gold badges304304 silver badges662662 bronze badges
JJaravaJJarava80822 gold badges1212 silver badges2323 bronze badges
5 Answers
These kind of things can be tricky in all Unix shells due to the way space is acting as a separator, running aliases as part of shell scripts just makes things even more interesting. I would probably run two passes of find to set first the directories in order, and then next the files:
bmike♦168k4646 gold badges304304 silver badges662662 bronze badges
nohillside♦nohillside57k1414 gold badges120120 silver badges168168 bronze badges
In general, the 'proper' way to parse the output of find into a bash loop is to use a
while read
loop, rather than a for
loop. In bash, for loops split using any whitespace (space, tab, newline) by default -- this can be changed, but it's easier and (in my opinion) cleaner to use read
, which reads one line at a time by default.Note that I quoted the
'$i'
there -- that's just as important, because quoting variables prevents the shell from splitting their contents (it's the same problem that for
has, but on the other end). Also note that you can't use single quotes: '$i'
would return a literal $i
, rather than the contents of the variable.This will still break on directories with newlines in their names. There is a workaround involving find's
-print0
, but I've only ever seen newlines in filenames specifically made to test scripts. I don't know if this works with the version of bash in OSX (taken from greg's wiki):However, in this case it's easier to use globs: a glob ending in a
/
will expand to directories only, so you could just(this will work perfectly well with spaces, newlines, anything). More generally, to loop through all directories:
Unfortunately, there is no way to select files only with globs in any version of bash (this is one of the reasons I prefer zsh, where the globs are powerful enough that you never have to bother with find).
evilsoupevilsoup
I have two suggestions:
- Use
sed
to put quotes around all the directory names. - Pipe to
xargs
with argument-L 1
. This will execute a command on each line of stdin, obviating thefor
loop.
Try this pipeline:
find . -maxdepth 1 -mindepth 1 -type d | cut -c 3- | sed 's/.*/'&'/' | xargs -L 1 chmod u+x
28822 gold badges33 silver badges1515 bronze badges
The crux of the issue is that word-splitting happens for command substitution, so that names with spaces in them are indistinguishable from separate names entirely. Globbing does not suffer from this difficulty, so if there's a way to identify directories with a glob and avoid the command substitution entirely, you're home free. And there is:
But even this is too much work, because
chmod
has the X
(capital X) symbolic flag, which applies the executable bit only to directories and files that are already executable. So you can really just do:kojirokojiro
Either your alias is only pulling the first bit before the space, or your for loop is only reading the first bit
Program For Loops In C
You can test this by adding some test commentary into your commands, I've limited the alias to only pull the last found directory to isolate the iterations to 1, printed out what the alias thinks it's receiving, and then echoed the variable contents to ensure they match:
EDIT: changed
do; echo ...
to do echo ...
as it was preventing the line from executingHow To Program For Loops In Mac Os Unix Based
JJarava80822 gold badges1212 silver badges2323 bronze badges
stuffeHow To Program For Loops In Mac Os Unix Password
stuffe23.2k1515 gold badges7373 silver badges128128 bronze badges