I have previously been successful with using the foreach
command with a space between subjects
and *
for example:
foreach subjects * : mrdegibbs IN/dwi_denoised.mif IN/dwi_denoised_unringed.mif -axes 0,1
I have been running the 'foreach'
command previously on bash with a space in between subjects and * and it seems to be executing fine.
For clarity, while this may work in your specific case, it is still nevertheless indicative of incorrect usage: @jdtournier hinted at this, but with a more technical description.
Let’s say, for instance, you have the following working directory contents:
$ ls
subjects_001/
subjects_002/
$
The purpose of what you type between “foreach
” and “:
” is to construct the list of elements for which the command after the “:
” will be executed. The “*
” wildcard is interpreted by the shell and replaced with a list of elements satisfied by that wildcard before foreach
is even invoked. In this case, both “subjects_001/
” and “subjects_002/
” satisfy the wildcard. But the string “subjects
” was provided separately to the wildcard, and is therefore its own entry in the list.
So what foreach
will actually “see” is:
foreach subjects subjects_001 subjects_002 : ...
It will then perform the appropriate substitutions and execute the following functions:
mrdegibbs subjects/dwi_denoised.mif subjects/dwi_denoised_unringed.mif -axes 0,1
mrdegibbs subjects_001/dwi_denoised.mif subjects_001/dwi_denoised_unringed.mif -axes 0,1
mrdegibbs subjects_002/dwi_denoised.mif subjects_002/dwi_denoised_unringed.mif -axes 0,1
The first of these commands will have failed, since almost certainly no such path exists. However if your list of subject directories is long, you may not have seen the corresponding error message.
The reason the advice of removing that space was given is because if you have more complicated working directory contents, e.g.:
$ ls
subjects_001/
subjects_002/
other.txt
$
, then:
foreach subjects * : ...
becomes:
foreach subjects subjects_001/ subjects_002/ other.txt : ...
; whereas:
foreach subjects/* : ...
becomes:
foreach subjects_001/ subjects_002/ : ...
, which is more likely what you intended.
With the coming update this will be improved: foreach
will report the number of inputs for which the corresponding command failed, and print only the terminal outputs of those failed invocations. It also provides a -test
option to check your usage and substitutions before running. 
Rob