Wednesday, May 8, 2024
 Popular · Latest · Hot · Upcoming
8
rated 0 times [  8] [ 0]  / answers: 1 / hits: 1147  / 3 Years ago, sat, september 25, 2021, 9:05:06

I have a directory called DS1. I am trying to copy it 4 times so I also have DS2, DS3, DS4 and DS5.


I am able to use the following command from the terminal and it works:


for i in {2..5}; do cp -r /home/test/DS1 "DS$i"; done

However, when I enter it into a script like this:


#!/bin/sh

for i in {2..5}; do cp -r /home/test/DS1 "DS$i"; done

It creates one directory named DS{2..5} instead of the directories with increments between 2 and 5. Not understanding what I'm doing wrong.


More From » bash

 Answers
6

{2..5} is brace expansion. Brace expansion is not standardized by POSIX. Some, but not all, of the widely used Bourne-style shells support it.


The shell you interact with in a terminal on Ubuntu is bash, unless you're deliberately using a different one. bash supports brace expansion. But the shebang on your script is for sh, which on Ubuntu is a symlink to dash. dash does not support brace expansion.


So you can either:



  1. Make your script a bash script (or a script for some other shell that supports brace expansion, such as zsh or ksh).

  2. Replace brace expansion in your script with something that works in dash.




If you want to make your script a bash script, replace


#!/bin/sh

with:


#!/bin/bash

Then when run like ./scriptname it will be run in bash. If you're running your script by writing sh scriptname then you must use bash scriptname instead.




If you want to eliminate brace expansion, there are a few alternatives. I suggest seq with command substitution, which is probably the most common alternative to brace expansion, is easy to write, and is likely to be understood by other human readers.


In place of {2..5}, you can write $(seq 2 5). Since it is not quoted--that is, since it is $( ) and not "$( )"--field splitting (which in bash is called word splitting) is performed on the result. So long as you have not set the IFS shell variable, which controls field splitting, to a value that contains any digit or that does not contain a newline, this will do what you want.


(Globbing--also called filename expansion, also called pathname expansion--is also performed on the result of unquoted command substitution, but the output of seq will not contain the globbing characters ?, *, or [, so that has no effect in this case.)


Note that seq is not standardized by POSIX. This will work on just about any GNU/Linux system and some other Unix-like operating systems, but some Unix-like OSes don't have seq installed by default (they usually have jot instead) so it is not guaranteed to work on all Unix-like operating systems.


[#2860] Sunday, September 26, 2021, 3 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
dicatandyca

Total Points: 486
Total Questions: 108
Total Answers: 121

Location: Greenland
Member since Wed, Jan 18, 2023
1 Year ago
;