To exec or not to exec
a call to exec replaces a shell's data, and therefore the shell can't return from an exec system call.
But not every command is the name of a program to execute. So often there is no exec
call involved. The key distinction is that in contrast to ( cmd1; cmd2; )
, you don't get another shell process. Or perhaps more correctly, the shell will only fork to execute child programs, not to execute shell processes.
Strange prompt
what does the command line belong.
As other answers have pointed out, your command was incomplete. So the command line belonged to bash itself, which was waiting for the end of your group.
Uses
Also, how is executing commands in the current shell in any way useful?
… as opposed to subshell grouping
The most prominent example is setting variables in that subcommand. Thy this:
foo=1; { foo=2; echo $foo; }; ( foo=3; echo $foo; ); echo $foo
This will print
2
3
2
So although you set foo=3
inside one group, that group was executed in a subshell and its settings didn't propagate to the parent.
Another thing worth considering is current working directory. { cd foo; make; }
will leave you in directory foo
whereas ( cd foo; make; )
will not alter the current working directory of your main shell.
… as opposed to ungrouped commands
The grouping is mostly useful if you have other code outside, e.g. conditionals
test -f foo && { echo "Foo exists."; rm foo; }
or redirections
{ echo "Content of $PWD:"; ls; } | gzip > dirlist.gz
The script below moves all files from one directory, containing your 535 folders, (recursively) into another (single) directory, keeping their original filename.
In case of duplicates
(Only) in case of duplicate names, files will be renamed to duplicate_1_[filename]
, duplicate_2_[filename]
etc.
How to use
Copy the script below into an empty file, save it as rearrange.py
, set the correct paths to the source and destination (directories) and run it by:
python rearrange.py
The script:
#!/usr/bin/env python
import os
import shutil
# --------------------------------------------------------
reorg_dir = "/path/to/sourcedirectory"
target_dir = "/path/to/destination"
# ---------------------------------------------------------
for root, dirs, files in os.walk(reorg_dir):
for name in files:
subject = root+"/"+name
n = 1; name_orig = name
while os.path.exists(target_dir+"/"+name):
name = "duplicate_"+str(n)+"_"+name_orig; n = n+1
newfile = target_dir+"/"+name; shutil.move(subject, newfile)
For (gnome-) terminal- "drag and drop" functionality:
Use below version, save it as described above (but don't change anything) and make it executable. To use it, open a terminal window, drag the script over the terminal window, then the source directory, last the destination. The command you'll then see in your terminal:
rearrange.py /path/to/source /path/to/destination
Press return and it is done.
The script:
#!/usr/bin/env python
import os
import shutil
import sys
# --------------------------------------------------------
reorg_dir = sys.argv[1]
target_dir = sys.argv[2]
# ---------------------------------------------------------
for root, dirs, files in os.walk(reorg_dir):
for name in files:
subject = root+"/"+name
n = 1; name_orig = name
while os.path.exists(target_dir+"/"+name):
name = "duplicate_"+str(n)+"_"+name_orig; n = n+1
newfile = target_dir+"/"+name; shutil.move(subject, newfile)
Copy instead of move
If you'd like to keep your current directory untouched and only copy the files into a new directory, simply replace the last (section of) line:
replace:
shutil.move(subject, newfile)
by:
shutil.copy(subject, newfile)
Best Answer
Yes, separate with a semi-colon like so:
Most lanugauges/shells use the semi-colon to signify the end of a command and to start new while evaluating from left to right.
Or as @RobieBasak recommends, use && instead of ; to guard against coding accidents.