Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.debian.user > #238168 > unrolled thread
| Started by | "Gary L. Roach" <garyroach719@gmail.com> |
|---|---|
| First post | 2021-08-05 02:00 +0200 |
| Last post | 2021-08-06 01:00 +0200 |
| Articles | 20 on this page of 35 — 13 participants |
Back to article view | Back to linux.debian.user
Bash script problem "Gary L. Roach" <garyroach719@gmail.com> - 2021-08-05 02:00 +0200
Re: Bash script problem Greg Wooledge <greg@wooledge.org> - 2021-08-05 02:10 +0200
Re: Bash script problem "Gary L. Roach" <garyroach719@gmail.com> - 2021-08-05 05:50 +0200
Re: Bash script problem john doe <johndoe65534@mail.com> - 2021-08-05 09:00 +0200
Re: Bash script problem <tomas@tuxteam.de> - 2021-08-05 10:10 +0200
Re: Bash script problem Greg Wooledge <greg@wooledge.org> - 2021-08-05 13:20 +0200
test vs. [ [was: Bash script problem] <tomas@tuxteam.de> - 2021-08-05 14:00 +0200
Re: test vs. [ [was: Bash script problem] Greg Wooledge <greg@wooledge.org> - 2021-08-05 14:40 +0200
Re: test vs. [ [was: Bash script problem] <tomas@tuxteam.de> - 2021-08-05 15:00 +0200
Re: Bash script problem Greg Wooledge <greg@wooledge.org> - 2021-08-05 14:30 +0200
Re: Bash script problem Anssi Saari <as@sci.fi> - 2021-08-05 09:40 +0200
Re: Bash script problem Tixy <tixy@yxit.co.uk> - 2021-08-05 10:30 +0200
Re: Bash script problem <tomas@tuxteam.de> - 2021-08-05 10:40 +0200
Re: Bash script problem Greg Wooledge <greg@wooledge.org> - 2021-08-05 14:00 +0200
Re: Bash script problem "Gary L. Roach" <garyroach719@gmail.com> - 2021-08-05 22:10 +0200
Re: Bash script problem Greg Wooledge <greg@wooledge.org> - 2021-08-05 22:20 +0200
Re: Bash script problem "Gary L. Roach" <garyroach719@gmail.com> - 2021-08-06 17:00 +0200
Re: Bash script problem <tomas@tuxteam.de> - 2021-08-06 17:10 +0200
Re: Bash script problem David <bouncingcats@gmail.com> - 2021-08-06 01:40 +0200
Re: Bash script problem Greg Wooledge <greg@wooledge.org> - 2021-08-06 02:10 +0200
Re: Bash script problem Polyna-Maude Racicot-Summerside <debian@polynamaude.com> - 2021-08-06 02:20 +0200
Re: Bash script problem Greg Wooledge <greg@wooledge.org> - 2021-08-06 02:30 +0200
Re: Bash script problem The Wanderer <wanderer@fastmail.fm> - 2021-08-06 03:50 +0200
Re: Bash script problem Greg Wooledge <greg@wooledge.org> - 2021-08-06 04:10 +0200
Re: Bash script problem Polyna-Maude Racicot-Summerside <debian@polynamaude.com> - 2021-08-06 02:10 +0200
Re: Bash script problem Christian Groessler <chris@groessler.org> - 2021-08-06 02:30 +0200
Re: Bash script problem Christian Groessler <chris@groessler.org> - 2021-08-06 03:00 +0200
Re: Bash script problem Greg Wooledge <greg@wooledge.org> - 2021-08-06 03:10 +0200
Re: Bash script problem David <bouncingcats@gmail.com> - 2021-08-06 03:10 +0200
Re: Bash script problem David <bouncingcats@gmail.com> - 2021-08-06 03:00 +0200
Re: Bash script problem <tomas@tuxteam.de> - 2021-08-06 09:00 +0200
Re: Bash script problem David Wright <deblis@lionunicorn.co.uk> - 2021-08-06 05:10 +0200
Re: Bash script problem David <bouncingcats@gmail.com> - 2021-08-06 05:50 +0200
Re: Bash script problem Darac Marjal <mailinglist@darac.org.uk> - 2021-08-06 09:20 +0200
Re: Bash script problem Tom Browder <tom.browder@gmail.com> - 2021-08-06 01:00 +0200
Page 1 of 2 [1] 2 Next page →
| From | "Gary L. Roach" <garyroach719@gmail.com> |
|---|---|
| Date | 2021-08-05 02:00 +0200 |
| Subject | Bash script problem |
| Message-ID | <CIyXL-4iY-1@gated-at.bofh.it> |
Hi all;
I have just recently delved into the magical world of Bash scripting and
programmed up the following script(not finished). The object is to parse
the Path and check for the existence of each directory. Please don't
send back an Awk or Sed statement that is more efficient. I am having
enough trouble with the Bash script.
Something is wrong with the logic of the if-fi statement. It is
triggered every time through the loop. The statement A="0; " seems to
be true no matter what the value of A. The if statement is there to
clear out the first item in the array that seems to be empty. Please help.
#!/bin/bash
set -x
#trap read debug
Path="/Test/gary/run/something"
IFS=/
read -a Array <<< $Path
for i in "${!Array[@]}"
do
A="${i} ; ${Array[i]}" #Load A
echo "A is equal to $A"
if [ A="0 ; " ]
then
echo "continuing"
continue
else
echo "Do rest of loop"
fi
done
Thanks in advance.
Gary R.
[toc] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2021-08-05 02:10 +0200 |
| Message-ID | <CIz7r-4BD-5@gated-at.bofh.it> |
| In reply to | #238168 |
On Wed, Aug 04, 2021 at 04:58:00PM -0700, Gary L. Roach wrote: > Path="/Test/gary/run/something" > IFS=/ > read -a Array <<< $Path You're setting IFS permanently for the whole script. It's usually better to set it only for the duration of the single read command which uses it. Also, read should always be used with the -r option, unless you want backslash mangling to occur. IFS=/ read -ra Array <<< "$Path" > if [ A="0 ; " ] This is incorrect, at least twice over. You need to separate each of the arguments of the [ command with whitespace. if [ A = "0 ; " ] It helps if you remember that [ is simply a fancy synonym for the test command. A more natural way to write this would be if test A = "0 ; " Next, you are comparing two constant strings, "A" and "0 ; ". This comparison is not useful, because they are always different strings. If A is a variable, then you probably meant to write this: if [ "$A" = "0 ; " ]
[toc] | [prev] | [next] | [standalone]
| From | "Gary L. Roach" <garyroach719@gmail.com> |
|---|---|
| Date | 2021-08-05 05:50 +0200 |
| Message-ID | <CICyl-6yN-3@gated-at.bofh.it> |
| In reply to | #238170 |
[Multipart message — attachments visible in raw view] — view raw
Thanks for the help but I still have the problem of the if statement always being true. This time I enclosed the file so you can test it. Gary R On 8/4/21 5:04 PM, Greg Wooledge wrote: > On Wed, Aug 04, 2021 at 04:58:00PM -0700, Gary L. Roach wrote: >> Path="/Test/gary/run/something" >> IFS=/ >> read -a Array <<< $Path > You're setting IFS permanently for the whole script. It's usually better > to set it only for the duration of the single read command which uses > it. Also, read should always be used with the -r option, unless you want > backslash mangling to occur. > > IFS=/ read -ra Array <<< "$Path" > >> if [ A="0 ; " ] > This is incorrect, at least twice over. You need to separate each of > the arguments of the [ command with whitespace. > > if [ A = "0 ; " ] > > It helps if you remember that [ is simply a fancy synonym for the test > command. A more natural way to write this would be > > if test A = "0 ; " > > Next, you are comparing two constant strings, "A" and "0 ; ". This > comparison is not useful, because they are always different strings. > If A is a variable, then you probably meant to write this: > > if [ "$A" = "0 ; " ] >
[toc] | [prev] | [next] | [standalone]
| From | john doe <johndoe65534@mail.com> |
|---|---|
| Date | 2021-08-05 09:00 +0200 |
| Message-ID | <CIFwd-8me-1@gated-at.bofh.it> |
| In reply to | #238175 |
On 8/5/2021 5:47 AM, Gary L. Roach wrote: > Thanks for the help but I still have the problem of the if statement > always being true. This time I enclosed the file so you can test it. > Two things: - Why is the var 'IFS' set above the read command? - What are you trying to do here? -- John Doe
[toc] | [prev] | [next] | [standalone]
| From | <tomas@tuxteam.de> |
|---|---|
| Date | 2021-08-05 10:10 +0200 |
| Message-ID | <CIGBX-Lf-1@gated-at.bofh.it> |
| In reply to | #238175 |
[Multipart message — attachments visible in raw view] — view raw
On Wed, Aug 04, 2021 at 08:47:30PM -0700, Gary L. Roach wrote:
> Thanks for the help but I still have the problem of the if statement
> always being true. This time I enclosed the file so you can test it.
Please, don't top quote. It confuses the hell out of me.
Now, I think in your script
if test A="0 ; "
should read
if test "$A" = "0 ; "
or, in the square bracket version:
if [ "$A" = "0 ; " ]
Basically, I'm repeating what Greg wrote, in somewhat other words. Greg's
mails are worth being read twice or three times.
Look carefully. Note a couple of things:
** white spaces around the "=":
`test' and its fancy cousin `[' are regular programs [1] invoked
by the shell: what follows are arguments which get interpreted by
`test', in this case, the args are "$A", = and "0 ; ", i.e. the
first arg, an operator (=) and the second arg. As always in the
shell, the args HAVE TO BE SEPARATED BY WHITESPACE (huh sorry for
raising my voice :)
** shell is not your regular php
the shell's power (and strangeness) derives from its text replacement
model. You have to bear that in mind. When the shell processes a
line, it does text replacements until it thinks it's ready, then
it invokes the command (typically a binary somewhere in $PATH, but
it can be a builtin, an alias or a function). In your case:
if test "$A" = "0 ; "
transforms to
if test "0 ; " = "0 ; "
...so the binary `test' gets to see three args (due to the quotes).
It dutily finishes with exit code 0, meaning "okidoki".
** watch those quotes
this follows a bit from the above. Imagine what happens if you lose
the quotes around "$A":
if test $A = "0 ; "
now transforms to
if test 0 ; = "0 ; "
Now test sees *four* arguments: "0", ";", "=" and "0 ; ". this
confuses the hell out of it and it balks at you:
bash: test: too many arguments
Shell programming is a tad different than Python, Perl, Ruby or what
you have. The textual replacement model takes some thought, but it
rewards you (as long as you use shells for what they were meant to).
I hope that gets you on track :)
And oh, in things shell, read Greg's mails. Perhaps also his wiki [2].
Cheers
[1] Nowadays this is a little white lie: most shells have them
as builtins, but they are supposed to behave like regular
programs, for compat. There /is/ a /bin/test, but I can't
find a /bin/[ on my system anymore.
[2] https://mywiki.wooledge.org/BashGuide/
-- tomás
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2021-08-05 13:20 +0200 |
| Message-ID | <CIJzP-2Cb-1@gated-at.bofh.it> |
| In reply to | #238183 |
On Thu, Aug 05, 2021 at 10:07:12AM +0200, tomas@tuxteam.de wrote: > [1] Nowadays this is a little white lie: most shells have them > as builtins, but they are supposed to behave like regular > programs, for compat. There /is/ a /bin/test, but I can't > find a /bin/[ on my system anymore. It's in /usr/bin on Debian. unicorn:~$ type -a test [ test is a shell builtin test is /usr/bin/test [ is a shell builtin [ is /usr/bin/[ unicorn:~$ ls -ld /usr/bin/[ /usr/bin/test -rwxr-xr-x 1 root root 60224 Sep 24 2020 '/usr/bin/[' -rwxr-xr-x 1 root root 56128 Sep 24 2020 /usr/bin/test I'm a bit surprised they're not the same program. And also that they're that large. And that different in size from each other. The external versions of test and [ need to exist for POSIX conformance, and also so that you can -exec them from find(1) or other similar programs.
[toc] | [prev] | [next] | [standalone]
| From | <tomas@tuxteam.de> |
|---|---|
| Date | 2021-08-05 14:00 +0200 |
| Subject | test vs. [ [was: Bash script problem] |
| Message-ID | <CIKcx-2Ph-3@gated-at.bofh.it> |
| In reply to | #238198 |
[Multipart message — attachments visible in raw view] — view raw
On Thu, Aug 05, 2021 at 07:19:11AM -0400, Greg Wooledge wrote: > On Thu, Aug 05, 2021 at 10:07:12AM +0200, tomas@tuxteam.de wrote: > > [1] Nowadays this is a little white lie: most shells have them > > as builtins, but they are supposed to behave like regular > > programs, for compat. There /is/ a /bin/test, but I can't > > find a /bin/[ on my system anymore. > > It's in /usr/bin on Debian. Ah, there it is, thanks. With all those young-uns shaking Unix's foundations, one never knows ;-P [...] > I'm a bit surprised they're not the same program. And also that they're > that large. And that different in size from each other. Yes, that's my recollection too: [ being a symlink to test (or even both being hardlinked together). This might betray my age... > The external versions of test and [ need to exist for POSIX conformance, > and also so that you can -exec them from find(1) or other similar > programs. I see. Do we still (seriously) care about POSIX (don't get me wrong: I'd strongly prefer a world where we did!). Cheers - t
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2021-08-05 14:40 +0200 |
| Subject | Re: test vs. [ [was: Bash script problem] |
| Message-ID | <CIKPf-3gC-1@gated-at.bofh.it> |
| In reply to | #238200 |
On Thu, Aug 05, 2021 at 01:59:06PM +0200, tomas@tuxteam.de wrote: > On Thu, Aug 05, 2021 at 07:19:11AM -0400, Greg Wooledge wrote: > > The external versions of test and [ need to exist for POSIX conformance, > > and also so that you can -exec them from find(1) or other similar > > programs. > > I see. Do we still (seriously) care about POSIX (don't get me wrong: I'd > strongly prefer a world where we did!). Depends on who you mean by "we". There are a bunch of people who do care, and a bunch of people who don't. I'd say the Debian developers who package things like coreutils care, at least to a certain degree. They won't go to extreme lengths to be POSIX compatible, but they'll mostly try to do so if it doesn't break anything or cause an unreasonable burden. A bigger issue is that certain packages which *should* be present for POSIX compatibility are simply not installed by default -- specifically, pax and ed come to mind. I don't know who made the decision that these packages would be "optional" instead of "standard", but it leaves significant holes in what would otherwise be a fairly POSIX-compliant operating system. Then again, users who care about having POSIX-compliant systems can simply install the extra packages they need, once they learn that they have this option. Maybe Debian believes that the small savings in disk space and bandwidth outweighs the merits of being closer to POSIX compatibility, since so few end users actually care about the latter. I can't say which decision is the better one.
[toc] | [prev] | [next] | [standalone]
| From | <tomas@tuxteam.de> |
|---|---|
| Date | 2021-08-05 15:00 +0200 |
| Subject | Re: test vs. [ [was: Bash script problem] |
| Message-ID | <CIL8B-3n6-1@gated-at.bofh.it> |
| In reply to | #238206 |
[Multipart message — attachments visible in raw view] — view raw
On Thu, Aug 05, 2021 at 08:32:39AM -0400, Greg Wooledge wrote: > On Thu, Aug 05, 2021 at 01:59:06PM +0200, tomas@tuxteam.de wrote: > > On Thu, Aug 05, 2021 at 07:19:11AM -0400, Greg Wooledge wrote: > > > The external versions of test and [ need to exist for POSIX conformance, > > > and also so that you can -exec them from find(1) or other similar > > > programs. > > > > I see. Do we still (seriously) care about POSIX (don't get me wrong: I'd > > strongly prefer a world where we did!). > > Depends on who you mean by "we". :-) > There are a bunch of people who do > care, and a bunch of people who don't. Yes, and I see that as a problem. > I'd say the Debian developers who package things like coreutils care, > at least to a certain degree. They won't go to extreme lengths to be > POSIX compatible, but they'll mostly try to do so if it doesn't break > anything or cause an unreasonable burden. [...] > I can't say which decision is the better one. I think this "soft POSIX compliance" might kill POSIX in the long run. Since everyone feels free to route around his/her personal pain points, there's little collective motivation to actually /fix/ them, and it might drift slowly into irrelevance. Now I'm not a 100% fan of POSIX /per se/ but I see the value in written standards. Standards processes can seem at times clumsy, but they force people to think about interfaces and specifications. Otherwise it's what we have now with WHATWG's HTML5 "living standard", which will end up with "whatever Google implements". Not much better, in my eyes, than the bad old times of Microsoft dominance. Cheers - t
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2021-08-05 14:30 +0200 |
| Message-ID | <CIKFz-3dJ-1@gated-at.bofh.it> |
| In reply to | #238175 |
On Wed, Aug 04, 2021 at 08:47:30PM -0700, Gary L. Roach wrote:
> Thanks for the help but I still have the problem of the if statement always
> being true. This time I enclosed the file so you can test it.
You didn't make the changes that I told you to make yesterday. But
this has already been covered in detail, by myself and others. Let's
move on to the bigger problems.
I can't tell what algorithm you're trying to use here, but it doesn't
look like it actually *works*. Let's go back to the beginning.
You're writing a script that wants to check that all of the components
of a pathname actually exist, right? So your input is something like
/usr/local/bin/youtube-dl
And you want to check whether /usr exists, and whether /usr/local exists,
and so on.
But what you've done is break the input into the following list of
words:
"" (the empty string)
usr
local
bin
youtube-dl
This isn't actually helpful. You don't want to check wither "local"
is a directory. You want to check whether "/usr/local" is a directory.
So, let's try to write a script that actually solves the problem. We'll
start by checking whether the whole input as given to us is an existing
file system entry of some kind. If it is, then we're already done --
all of the components exist, and there's nothing more to check.
If the input isn't an existing entry, then we'll strip off the last
component, check again, and so on until we reach a pathname that *does*
exist.
Here's a rough first approximation which does those things. It may
not act precisely how you would like in all of the corner case inputs,
so some adjustments may be desirable. But it's a good starting point.
#!/bin/bash
# If the input exists, we're done.
if [[ -e "$1" ]]; then
echo "<$1> exists"
exit 0
fi
# Otherwise, keep shortening it until we find something that exists,
# or we run out of pathnames to try.
f="$1"
echo "<$f> does not exist"
while [[ "$f" = */* ]]; do
f="${f%/*}"
if [[ -e "$f" ]]; then
echo "<$f> exists"
break
else
echo "<$f> does not exist"
fi
done
exit 1
And, testing it:
unicorn:~$ ./foo /usr/local/bin
</usr/local/bin> exists
unicorn:~$ ./foo /usr/local/bin/rogue
</usr/local/bin/rogue> does not exist
</usr/local/bin> exists
unicorn:~$ ./foo /usr/local/sbin/rogue
</usr/local/sbin/rogue> does not exist
</usr/local/sbin> exists
unicorn:~$ ./foo /usr/local/xbin/rogue
</usr/local/xbin/rogue> does not exist
</usr/local/xbin> does not exist
</usr/local> exists
unicorn:~$ ./foo /urs/local/bin
</urs/local/bin> does not exist
</urs/local> does not exist
</urs> does not exist
<> does not exist
unicorn:~$ ./foo xyz
<xyz> does not exist
You will probably have questions about some of the syntax that I used.
Go ahead and ask them.
[toc] | [prev] | [next] | [standalone]
| From | Anssi Saari <as@sci.fi> |
|---|---|
| Date | 2021-08-05 09:40 +0200 |
| Message-ID | <CIG8V-m5-3@gated-at.bofh.it> |
| In reply to | #238168 |
"Gary L. Roach" <garyroach719@gmail.com> writes: > Hi all; > > I have just recently delved into the magical world of Bash scripting > and programmed up the following script(not finished). The object is to > parse the Path and check for the existence of each directory. Please > don't send back an Awk or Sed statement that is more efficient. I am > having enough trouble with the Bash script. Well, are trying to check the existence of each part of each path element? So for example, first check /Test exists, then /Test/gary, then /Test/gary/run and so on? Because just checking the directories in $PATH is much easier, just read $PATH into an array and iterate over it and you can use test or [ with -d to see if a directory exists. For the weird code you have, well, I avoid bash scripting since I prefer the zsh shell and especially its clearer array syntax. Anyways, for some reason [ A="0 ; " ] is always true. It seems it probably has something to do with expansion, quoting and the special meaning of ;. Changing the line to if [ $A = '0 ; ' ] seems to work.
[toc] | [prev] | [next] | [standalone]
| From | Tixy <tixy@yxit.co.uk> |
|---|---|
| Date | 2021-08-05 10:30 +0200 |
| Message-ID | <CIGVk-Ry-7@gated-at.bofh.it> |
| In reply to | #238179 |
On Thu, 2021-08-05 at 10:36 +0300, Anssi Saari wrote: [...] > > [ A="0 ; " ] > > is always true. It seems it probably has something to do with expansion, > quoting and the special meaning of ;. > ; has no special meaning inside "". The expression is true because there is only a single non-null argument between the [ ] -- Tixy
[toc] | [prev] | [next] | [standalone]
| From | <tomas@tuxteam.de> |
|---|---|
| Date | 2021-08-05 10:40 +0200 |
| Message-ID | <CIH4Z-UG-1@gated-at.bofh.it> |
| In reply to | #238188 |
[Multipart message — attachments visible in raw view] — view raw
On Thu, Aug 05, 2021 at 09:26:35AM +0100, Tixy wrote: > On Thu, 2021-08-05 at 10:36 +0300, Anssi Saari wrote: > [...] > > > > [ A="0 ; " ] > > > > is always true. It seems it probably has something to do with expansion, > > quoting and the special meaning of ;. > > > > ; has no special meaning inside "". The expression is true because > there is only a single non-null argument between the [ ] Yes, well put. As much as [ foobarbazxy ] is always true :-) I always recommend `echo' to those who want to "see" argument expansion before pulling out their hair. Try echo A="0 ; " => A=0 ; Since whitespace is so difficult to see, let's prepend and postpend something (the `-n' option tells echo to not output a newline): echo -n '<' ; echo -n A="0 ; " ; echo '>' => <A=0 ; > Cheers - t
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2021-08-05 14:00 +0200 |
| Message-ID | <CIKcx-2Ph-9@gated-at.bofh.it> |
| In reply to | #238189 |
On Thu, Aug 05, 2021 at 10:38:47AM +0200, tomas@tuxteam.de wrote: > On Thu, Aug 05, 2021 at 09:26:35AM +0100, Tixy wrote: > > ; has no special meaning inside "". The expression is true because > > there is only a single non-null argument between the [ ] Precisely. But you're probably not explaining it in a way the OP will understand. Let's come back to that in a moment. > echo A="0 ; " > => A=0 ; I'm not sure that helps much. > echo -n '<' ; echo -n A="0 ; " ; echo '>' > => <A=0 ; > Why not simply echo "A=<$A>" ? (Or printf, to be safer, but we'll save that for a different email. The OP doesn't seem able to absorb too many concepts at once.) Now, as promised, How The Test Command Works. The test command evolved over time. There are several different original versions with slightly different behaviors, and even modern shells offer some extensions to the basic standard. In order to make everything consistent, POSIX decreed that test shall work as follows: The first thing it does is *COUNT* the number of arguments that it receives. It is impossible to overstate the importance of this. No matter how much you think your test command looks like it should do XYZ, it's the number of arguments that determines what it actually does. As Tixy said, when you have [ A="foo" ] you are passing *one* argument to test. (Two arguments to the [ form, but the final ] argument gets removed, so in the end, it's one argument that actually counts.) When test is given one argument, what it does is check the *length* of that argument. If the length is 0, the expression is treated as "false", and test exits with status 1 (false/failure). Otherwise, if the length is not 0, it's treated as "true", and test exits with status 0 (true/success). It doesn't matter *what* the string is. All of the following generate a "true" result: test foobar test true test false test 0 test 1 test A=B test 2+2=5 test 'your mother was a hamster' test "$a=$b" It doesn't matter what the argument is, as long as it's not the empty string. In that last example, it doesn't even matter what $a and $b expand to. We're guaranteed there's at least an = sign in between them, so we know it will never be an empty string. When test is given *two* arguments, there are two valid forms that it will look for: test ! somestring test -? something That is, the first argument must be either a literal exclamation point, or it must be a unary test operator which is spelled with a hyphen and then some letter (-e or -d or -x, etc.). If the first argument isn't either of those, the result is "unspecified". It will probably be an error, unless your shell overrides it for some reason. unicorn:~$ test one two bash: test: one: unary operator expected If the first argument is ! then it simply does the reverse of the one-argument check. It looks at the length of the second argument. If the second argument is the empty string, test exits with status 0 (success/true). If the second argument is *not* the empty string, it exits with status 1 (failure/false). If the first argument is one of the unary operators, such as -d, then the corresponding test is performed on the second argument. In the case of -d, it means "check whether the second argument is a directory". And so on. There are also 3-argument and 4-argument forme, but I'm not going to cover them here, because this is already long enough, and I'm basically just repeating the POSIX man page with extra details and examples. If you want to read the official documentation, it's at https://pubs.opengroup.org/onlinepubs/9699919799/utilities/test.html or if you prefer, you can install the manpages-posix package, and then run "man 1posix test". So, what does all of this actually mean? It means you *cannot* omit the whitespace when you write your test (or [) commands. These are correct: test "$a" = b [ "$a" = b ] These are *not* correct: test "$a"=b [ "$a"=b ] ["$a" = b] ["$a"=b] And so on. See also <https://mywiki.wooledge.org/BashPitfalls#pf10>, and the pitfall after that, or for bonus credit, the entire BashPitfalls page.
[toc] | [prev] | [next] | [standalone]
| From | "Gary L. Roach" <garyroach719@gmail.com> |
|---|---|
| Date | 2021-08-05 22:10 +0200 |
| Message-ID | <CIRQJ-7vr-1@gated-at.bofh.it> |
| In reply to | #238202 |
[Multipart message — attachments visible in raw view] — view raw
hi all; I really appreciate all of your help. The file now works. See attached. Now t0 answer some questions. First, the IFS command sets the string separator. The default values are space /n and one other. The / is not among them. If I don't set the delimiter before I do the read, the whole string is read into the first array slot. Not what I want. Also, it may be bad practice to set this globally but if it starts to cause trouble later I can just reset it to the default values. Second, why am I separating out the Path the way I am doing? I need to check each level for existence then, if the level doesn't exist, create the directory, cd to the directory, set chown and -x chmod. After that check the next level and repeat the process until I run out of levels. There are other things that need to be done with files that are similar. I want to use this .sh file to automatically set up the Amanda backup system . I just got burned bad because of no backup.(dumb I know). I've had so much trouble setting up backup systems that I gave up the last time. I want to write this procedure once and store it away on a flash drive so that the next time I get a major crash I can pull out the flash drive and restore things easily. The code that I furnished is a test bed for part of the working file and will be incorporated into a function in the final program. My approach may not be very elegant but if it works, frankly, I don't care. To all of you: The problem, as several of you pointed out, was with the if statement syntax. It is now fixed and is working fine. A copy is attached. All of you help has been sincerely appreciated. Gary R.
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2021-08-05 22:20 +0200 |
| Message-ID | <CIS0q-7yz-1@gated-at.bofh.it> |
| In reply to | #238223 |
On Thu, Aug 05, 2021 at 01:03:16PM -0700, Gary L. Roach wrote:
> First, the IFS command sets the string separator. The default values are
> space /n and one other. The / is not among them.
Yes, we know that. The issue is that you are setting IFS for the
whole script, when you probably *should* be setting it only for a
single command.
Compare the following two blocks of commands:
IFS=/
read -ra array
vs.
IFS=/ read -ra array
The former is what *you* are doing. This sets IFS permanently, for
the duration of the script or the current subshell (or function, if
you previously declared IFS to be local inside a function).
The latter is what we keep telling you to do. You keep not doing it.
> Second, why am I separating out the Path the way I am doing? I need to check
> each level for existence then, if the level doesn't exist, create the
> directory, cd to the directory, [...]
Why can't you just mkdir -p the final directory? This creates the
parent directories as needed.
> [...] set chown and -x chmod. After that check the
> next level and repeat the process until I run out of levels.
What do you mean by "-x chmod"? A directory *needs* the +x permission bit
to be set in order to function properly.
file=/opt/foobar/share/foobar.conf
dir=${file%/*}
mkdir -p "$dir"
touch "$file"
You're doing *way* too much work. It's a gigantic X-Y problem.
> I want to use this .sh file to automatically set up the Amanda backup system
I don't know Amanda, so I can't help you with that part.
[toc] | [prev] | [next] | [standalone]
| From | "Gary L. Roach" <garyroach719@gmail.com> |
|---|---|
| Date | 2021-08-06 17:00 +0200 |
| Message-ID | <CJ9uh-10P-3@gated-at.bofh.it> |
| In reply to | #238224 |
On 8/5/21 1:15 PM, Greg Wooledge wrote:
> On Thu, Aug 05, 2021 at 01:03:16PM -0700, Gary L. Roach wrote:
>> First, the IFS command sets the string separator. The default values are
>> space /n and one other. The / is not among them.
> Yes, we know that. The issue is that you are setting IFS for the
> whole script, when you probably *should* be setting it only for a
> single command.
Oops. I guess I just misunderstood what you were saying. I made the
change to IFS=/ read ... Works fine.
>> Second, why am I separating out the Path the way I am doing? I need to check
>> each level for existence then, if the level doesn't exist, create the
>> directory, cd to the directory, [...]
> Why can't you just mkdir -p the final directory? This creates the
> parent directories as needed.
I've been using Debian for a long time but didn't realize you could do
that. Well back to the drawing board.
>> [...] set chown and -x chmod. After that check the
>> next level and repeat the process until I run out of levels.
>>
>> What do you mean by "-x chmod"? A directory *needs* the +x permission bit
>> to be set in order to function properly.
Oops. The -x is a typo. S/B +x.
>> file=/opt/foobar/share/foobar.conf
>> dir=${file%/*}
>> mkdir -p "$dir"
>> touch "$file"
>>
>> You're doing *way* too much work. It's a gigantic X-Y problem.
I agree. I'm going back through the code and rewriting most of it.
>> I want to use this .sh file to automatically set up the Amanda backup system
> I don't know Amanda, so I can't help you with that part.
>
That part I can work out with time. Again thanks for the help.
I'm 85 years old and the brain sometimes isn't as adgal as it used to
be. The short term memory sucks.
Gary R.
[toc] | [prev] | [next] | [standalone]
| From | <tomas@tuxteam.de> |
|---|---|
| Date | 2021-08-06 17:10 +0200 |
| Message-ID | <CJ9DY-1jK-19@gated-at.bofh.it> |
| In reply to | #238268 |
[Multipart message — attachments visible in raw view] — view raw
On Fri, Aug 06, 2021 at 07:52:20AM -0700, Gary L. Roach wrote: > > On 8/5/21 1:15 PM, Greg Wooledge wrote: [...] > >>You're doing *way* too much work. It's a gigantic X-Y problem. > I agree. I'm going back through the code and rewriting most of it. OTOH... this is how most learning journeys start, isn't it? ;-) Cheers - t
[toc] | [prev] | [next] | [standalone]
| From | David <bouncingcats@gmail.com> |
|---|---|
| Date | 2021-08-06 01:40 +0200 |
| Message-ID | <CIV7X-QV-1@gated-at.bofh.it> |
| In reply to | #238223 |
On Fri, 6 Aug 2021 at 06:03, Gary L. Roach <garyroach719@gmail.com> wrote: > Second, why am I separating out the Path the way I am doing? I need to > check each level for existence then, if the level doesn't exist, create > the directory, cd to the directory, set chown and -x chmod. After that > check the next level and repeat the process until I run out of levels. > There are other things that need to be done with files that are similar. It sounds like you are unaware of 'mkdir -p' and 'chown -R'. They are the standard tools for this kind of task. 'chmod -R' is less useful because it does not discriminate between files and directories, I never understood why it does not offer that option, because usually we need all file permissions to not be the same as all directory permissions.
[toc] | [prev] | [next] | [standalone]
| From | Greg Wooledge <greg@wooledge.org> |
|---|---|
| Date | 2021-08-06 02:10 +0200 |
| Message-ID | <CIVAZ-1fl-1@gated-at.bofh.it> |
| In reply to | #238228 |
On Thu, Aug 05, 2021 at 08:01:22PM -0400, Polyna-Maude Racicot-Summerside wrote:
> find . -type d -exec chmod -v 0644 '{}' \;
>
> to change the folder
>
> find . -type f -exec chmod -v 0755 '{}' \;
>
> to change files
You've switched the permissions around. You want 644 on the files, and
755 on the directories.
Use + instead of \; to make them more efficient. Also, you don't need
to quote the {} argument. I've never been able to figure out where
that tradition came from, because I've never seen *any* shell where
it's needed. But at least it's harmless.
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | linux.debian.user
csiph-web