Given two directories; dira and dirb, how can I make subdirectories using curly brace expansion in mkdir command?
For instance, I have tried: mkdir -p {dira, dirb}/sub. This results in two new directories called {dira, and dirb}. Instead, I would like instead to have dira/sub and dirb/sub.
I am running the following version:
GNU bash, version 3.2.51(1)-release (x86_64-apple-darwin13)
Copyright (C) 2007 Free Software Foundation, Inc.
Try:
$ mkdir -p {dira,dirb}/sub
$ find .
.
./dirb
./dirb/sub
./dira
./dira/sub
Using GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu)
Related
I am trying to understand the following (odd?) behavior on my setup. I am running Windows 10, with WSL.
Here is what I see from my powershell+wsl session:
$ ./run.sh
Windows IP Configuration
<cut>
1
with:
$ cat run.sh
#!/bin/bash
mkdir -p dir/1
mkdir -p dir/2
mkdir -p dir/3
var=0
while read i;
do
((var++))
ipconfig.exe
done < <(find dir -type d)
echo $var
If I now comment out the ipconfig.exe line:
...
#ipconfig.exe
...
Here is now what I get:
$ ./run.sh
4
Why calling a window executable (eg. ipconfig.exe) seems to interfere with my while loop using process substitution) ?
For reference:
$ uname -a
Linux FR-L0002146 5.10.102.1-microsoft-standard-WSL2 #1 SMP Wed Mar 2 00:30:59 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
and
$ bash -version
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Most likely ipconfig.exe is reading from stdin, so it's sucking up the input from the process substitution. Redirect its input to /dev/null to prevent this.
while read i;
do
((var++))
ipconfig.exe </dev/null
done < <(find dir -type d)
For Example to simulate the issue, execute following in linux (CentOS 7)
## create temporary destination directory
mkdir -p /tmp/b/
## create temporary file to move to destination directory
touch /tmp/a.txt
## execute move
mv -v /tmp/a.txt -t /tmp/b/
renamed '/tmp/a.txt' -> '/tmp/b/a.txt'
As you can see above the verbose output says "renamed" instead of moved, is there any way we can make it print to moved (without piping and replacing words using sed/awk)
$ /bin/mv --version
mv (GNU coreutils) 8.22
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Mike Parker, David MacKenzie, and Jim Meyering.
mvuses the underlying rename system command. Hence it's logical that the mv action reports a 'rename' event.
B=master U='my.email#email.com' curl -u "${U}" "https://bitbucket.org/myteam/pod-dev/raw/${B}/install.bash"
I get asked:
Enter host password for user '':
See, the "U" is missing.
And also curl is performed:
GET /myteam/pod-dev/raw//install.bash HTTP/1.1
Also here, the B is missing (branch)
macOS Sierra 10.12.2
$ bash --version
GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin16)
Copyright (C) 2007 Free Software Foundation, Inc.
Variables assignments like you are using them are part of the command. In your case the shell will try to expand "${A}", "${B}" before they have been actually set - during parsing the command.
You can separate the variable assignments and the actual command by ;:
B=master; U='my.email#email.com'; curl -u "${U}" "https://bitbucket.org/myteam/pod-dev/raw/${B}/install.bash"
That way they are 3 separate commands.
bash will try to expand the variables first, but you haven't set them at this point. See for example:
$ x=foo echo "$x"
>
$ x=foo; echo "$x"
> foo
Try like this instead of your command:
export B=master; export U='my.email#email.com' ; curl -u "$U" "https://bitbucket.org/myteam/pod-dev/raw/$B/install.bash"
When I try to run some Bash scripts on a Windows XP machine using MinGW, I get the following error:
./autogen.sh: pipe error: No such file or directory
I have localised the problem to Bash lines such as the following, which have a pipe inside backticks:
__copyright="`grep Copyright ./autogen.sh | head -1`"
However, pipes not inside backticks work just fine:
grep Copyright ./autogen.sh | head -1
All the programs you expect (sh, head, grep) are available and run happily on the command line and in Bash.
What should I do to resolve this error? I cannot run most Bash build tools without it.
$ msysinfo | head -3
msysinfo-1.3: Send this to the MSYS support list:
MSYS 1.0.11(0.46/3/2) 2004-04-30 18:55 i686 unknown; targ=MINGW32
$ echo '__copyright="`grep Copyright ./autogen.sh | head -1`" && echo $__copyright' >test.sh
$ cat test.sh
__copyright="`grep Copyright ./autogen.sh | head -1`" && echo $__copyright
$ sh test.sh
# Copyright 2005, 2006, 2007, 2008 by
For this test, I copied autogen.sh from some place like... randomly... http://svn.ghostscript.com/ghostscript/tags/freetype-2.3.7/autogen.sh
Probably this means your question needs more information.
But... sometimes when I run into snarly scenarios, it can help to enclose the breaking code in ( ). Technically, also, you do not need " " around backticks, and that complicates some use, but your example does not seem problematic.
I really hate to propose the following as it seems completely unnecessary:
$ for item in `grep Copyright ./autogen.sh`;
do
__copyright="$__copyright $item";
done;
echo $__copyright
What is more weird is that your error message seems to imply autogen.sh itself generated the error as though autogen.sh was grepping itself so I did:
$ sh test.sh
__copyright="`grep Copyright ./test.sh | head -1`" && echo $__copyright
after modifying test.sh to grep itself, and even that worked.
It therefore sounds like a sequencing issue and not a backtick issue, you know, which came first, the chicken or the egg?
Is autogen.sh trying to read its own Copyright comment? One way to let comments serve as data is to wrap them in here documents:
_Copyright ()
{
cat <<-END_OF_TEXT
# Copyright 2012, me
END_OF_TEXT
}
_Copyright
This topic is about the util 'ls'
The BSD version uses the parameter '-G' to color up the output,
while the Linux version uses parameter '--color'
Also the environment variable to set the colors is different:
BSD: $LSCOLORS
Linux: $LS_COLORS
But now the problem is: I want to determine which version is installed (using a small Shell script), so I can set alias ls and the environment appropriate in my .bachrc file.
As I mentioned above this seems to me to be the handiest method
if ls --color -d . >/dev/null 2>&1; then
GNU_LS=1
elif ls -G -d . >/dev/null 2>&1; then
BSD_LS=1
else
SOLARIS_LS=1
fi
I've essentially this in my l script, which I use on various platforms to tweak ls output as I like
Just run 'ls' and see whether it throws an error, e.g. on my mac:
$ ls --color 1>/dev/null 2>&1
$ echo $?
1
Whereas
$ ls -G 1>/dev/null 2>&1
$ echo $?
0
Indicating -G is supported, but --color is not.
Ironically, the --version switch Kimmo mentions is not supported on most BSD systems :-)
Writing a portable configuration file for your particular setup can be a Herculean task. In your case, if you're sure your .bashrc is going to be used only on GNU/Linux and on a BSD system, you can check for switches that exist in one of the ls' but not in the other: for example, -D doesn't seem to be an accepted switch by ls on my BSD machines (FreeBSD and Mac OS X), whereas it is for GNU ls. Conversely, -P is accepted on BSD, but not on GNU/Linux. Knowing this, you can distinguish between the two ls' and set up environment variables accordingly.
$ ls --version
ls (GNU coreutils) 6.10
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Richard Stallman and David MacKenzie.
combining the methods described, here's an easy way to use a bash function instead of an alias in order to make colors work regardless of if you are using BSD or GNU ls.
ll () {
if ls --version &>/dev/null; then
ls --color=auto -lahtr
else
ls -Glahtr
fi
}
inspired by a particular conda env recipe pulling in GNU ls on my macOS system where my ls aliases were all hard-coded for stock BSD ls only.