Re: Bash – am I getting MAD here?

Johnny Rosenberg gurus.knugum at gmail.com
Wed Jul 27 22:20:49 UTC 2016


2016-07-27 22:01 GMT+02:00 Jared Greenwald <greenwaldjared at gmail.com>:

> On Wed, Jul 27, 2016 at 2:48 PM, Johnny Rosenberg <gurus.knugum at gmail.com>
> wrote:
>
>> 2016-07-27 19:08 GMT+02:00 Jared Greenwald <greenwaldjared at gmail.com>:
>>
>>> The problem you have is that of namespace.  Even though you're declaring
>>> the "FileName" variable within ToURI as a local, you're also declaring it
>>> in the global context in the (now disabled) line.  It wouldn't necessarily
>>> be a problem, but you're declaring FileName as an array in the global
>>> context, so when you go to use it the ToURI context, bash basically doesn't
>>> know what to do with an assignment to an array without a positional
>>> reference.  Basically, you *could* override the global value in ToURI if
>>> you wanted to by using a positional reference (eg [1]) or remove the
>>> positional reference in the global context. My best suggestion would be to
>>> just change the local variable name in ToURI to something that doesn't
>>> collide with the global namespace.
>>>
>>
>> I think I see what you mean.
>> About the array thing, I actually found later that replacing *FileName[1]=$(basename
>> "${File[1]}") with **FileName=$(basename "${File[1]}") *worked too, and
>> that was also my first solution, giving a slightly slower script, not
>> noticeable though.
>>
>
> Without the context of the larger script, it's hard to say what might be
> causing the issue.  The small snippet doesn't really justify to me the use
> of an array, but the larger context might.  In the past, I've only really
> used arrays in bash when it was absolutely necessary since there are plenty
> of other ways to skin that cat.
>
>
>>
>> Having another look at my ToURI function, I'm also wondering if ”*export
>> local*” is meaningful. Sounds like a contradiction… But I need the
>> export for the perl thing at the end of the function, I don't think it will
>> work otherwise.
>>
>
> I doubt that it has any implication.  The "export" is really the only
> thing you needed there I think and as someone else pointed out, you can
> just do it in one line.  Cleaner and more concise.
>
>
>>
>> However, I replaced FileName in the ToURI function with InputFile and it
>> seems to work now.
>>
>
> Yea, really anything would have worked there as long as it wasn't FileName.
>
>
>> Thank you very much for your input. I guess I should have understood this
>> myself, but I'm good at other things… :P
>>
>
> I'm certainly no expert in bash.  As shown by the fact that others pointed
> out things I didn't see.  The only way to learn and make better code is to
> try what you know and then get input and advice from others.
>

True. I have learned a lot by just making mistakes, scratching my head,
asking questions and being corrected (in that order…). Thanks to you and
everyone who have been helpful!



Kind regards

Johnny Rosenberg



>
>
>>
>>
>> Kind regards
>>
>> Johnny Rosenberg
>>
>>
>>
>>>
>>> On Wed, Jul 27, 2016 at 11:59 AM, Johnny Rosenberg <
>>> gurus.knugum at gmail.com> wrote:
>>>
>>>> Hi!
>>>>
>>>> I really really don't understand what's going on here. I have a rather
>>>> big script and there is something that doesn't work properly, and after
>>>> hours of debugging, I found the problem line.
>>>>
>>>> Since the script is very big, 19 files at the moment, I made a shorter
>>>> example that has exactly the same problem. Here it is:
>>>>
>>>> *#!/bin/bash*
>>>>
>>>> *FullPathName() {*
>>>> * # Declare local variables*
>>>> * local Path="$1"*
>>>> * if [[ ${Path:0:1} != / ]]; then # Relative path.*
>>>> * echo "${PWD}/${Path}"*
>>>> * else # Absolute path.*
>>>> * echo "${Path}"*
>>>> * fi*
>>>> *}*
>>>>
>>>> *ToURI () {*
>>>> * # Declare local variables.*
>>>> * export local FileName="$1"*
>>>> * perl -MURI::file -e 'print URI::file->new($ENV{'FileName'})."\n"'*
>>>> *}*
>>>>
>>>> *File[1]=$(FullPathName "${1}")*
>>>> *FileName[1]=$(basename "${File[1]}")*
>>>>
>>>> *SelectedProject="Projekt Johnny Guitar"*
>>>> *RemoteRootFolder="http://web.comhem.se/something
>>>> <http://web.comhem.se/something>"*
>>>> *RemoteProjectFolder="${RemoteRootFolder}/"$(ToURI
>>>> "${SelectedProject}")*
>>>>
>>>> *echo "${RemoteProjectFolder}"*
>>>>
>>>> as you can see, the *File* and *FileName* variables are not used for
>>>> anything in this example, but they still illustrate the problem. I named
>>>> the file *TEST.sh*, put it in my *~/bin* folder which is included in
>>>> my *PATH* environment variable, so I will run this test with a random
>>>> file as an argument.
>>>>
>>>> Now, let's run this:
>>>> *~$ TEST.sh .netrc*
>>>> *http://web.comhem.se/something/ <http://web.comhem.se/something/>*
>>>> *~$ *
>>>> Obviously, *$(ToURI "${SelectedProject}" *didn't do anything, but why?
>>>>
>>>> So, as I said, after hours of debugging, I came up with this:
>>>> *#!/bin/bash*
>>>>
>>>> *FullPathName() {*
>>>> * # Declare local variables*
>>>> * local Path="$1"*
>>>> * if [[ ${Path:0:1} != / ]]; then # Relative path.*
>>>> * echo "${PWD}/${Path}"*
>>>> * else # Absolute path.*
>>>> * echo "${Path}"*
>>>> * fi*
>>>> *}*
>>>>
>>>> *ToURI () {*
>>>> * # Declare local variables.*
>>>> * export local FileName="$1"*
>>>> * perl -MURI::file -e 'print URI::file->new($ENV{'FileName'})."\n"'*
>>>> *}*
>>>>
>>>> *File[1]=$(FullPathName "${1}")*
>>>> *# FileName[1]=$(basename "${File[1]}") ############## Disabled line
>>>> ###############*
>>>>
>>>> *SelectedProject="Projekt Johnny Guitar"*
>>>> *RemoteRootFolder="http://web.comhem.se/something
>>>> <http://web.comhem.se/something>"*
>>>> *RemoteProjectFolder="${RemoteRootFolder}/"$(ToURI
>>>> "${SelectedProject}")*
>>>>
>>>> *echo "${RemoteProjectFolder}"*
>>>>
>>>> So, the only difference is that I disabled the line *FileName[1]=$(basename
>>>> "${File[1]}")*.
>>>>
>>>> Now, let's try again:
>>>> *~$ TEST.sh .netrc*
>>>> *http://web.comhem.se/something/Projekt%20Johnny%20Guitar
>>>> <http://web.comhem.se/something/Projekt%20Johnny%20Guitar>*
>>>> *~$ *
>>>>
>>>> So, suddenly it works, but WHY?
>>>> I early suspected *basename*, but in the original script there are
>>>> several *basename* statements, but they don't mess anything up.
>>>>
>>>>
>>>> Seriously, what is going on here?
>>>>
>>>> *~$ bash --version | grep release*
>>>> *GNU bash, version 4.3.11(1)-release (i686-pc-linux-gnu)*
>>>> *~$*
>>>>
>>>>
>>>>
>>>> *Any help is greatly appreciated, since this is a real showstopper for
>>>> me at the moment.*
>>>>
>>>> --
>>>> ubuntu-users mailing list
>>>> ubuntu-users at lists.ubuntu.com
>>>> Modify settings or unsubscribe at:
>>>> https://lists.ubuntu.com/mailman/listinfo/ubuntu-users
>>>>
>>>>
>>>
>>> --
>>> ubuntu-users mailing list
>>> ubuntu-users at lists.ubuntu.com
>>> Modify settings or unsubscribe at:
>>> https://lists.ubuntu.com/mailman/listinfo/ubuntu-users
>>>
>>>
>>
>> --
>> ubuntu-users mailing list
>> ubuntu-users at lists.ubuntu.com
>> Modify settings or unsubscribe at:
>> https://lists.ubuntu.com/mailman/listinfo/ubuntu-users
>>
>>
>
> --
> ubuntu-users mailing list
> ubuntu-users at lists.ubuntu.com
> Modify settings or unsubscribe at:
> https://lists.ubuntu.com/mailman/listinfo/ubuntu-users
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ubuntu.com/archives/ubuntu-users/attachments/20160728/0bb7a7d7/attachment.html>


More information about the ubuntu-users mailing list