Why does this shell script fail if I split it in two lines?
-
20-12-2019 - |
Pergunta
I'm very comfortable using the shell, but I don't know much about shell scripting. Today I cam across a tiny shell script for fixing the node-webkit libudev.so.0 problem: https://github.com/rogerwang/node-webkit/wiki/The-solution-of-lacking-libudev.so.0
As you can see, solution one instructs to create a shell script with the following code in it:
LD_LIBRARY_PATH=/home/omi/nw:$LD_LIBRARY_PATH ./nw $*
My understanding of what is happening is the following:
1) Declare the variable LD_LIBRARY_PATH, and assign a value to it, in this case it is the path to the nw directory where we have previously created a symlink to libudev.so.1. Then, append the previous value of $LD_LIBRARY_PATH to the new value. Then execute the nw binary passing the arguments that were passed to the shell script.
This works well, as expected, but if I split the code in two lines like so:
LD_LIBRARY_PATH=/home/omi/nw:$LD_LIBRARY_PATH
./nw $*
It does not work. The shell script executes without any errors, but the node-webkit application doesn't run. Instead we get the error about libudev.so.0 missing. Why is that?
Also, it seems like the path you add (/home/omi/nw in this case) can be anything. I tried using /home/, /home/akjfd/, and other variations, and the script always worked as expected. Why is that? (I finally left it with the correct path pointing to where I created the symlink)
PS. A bit out of topic, I found out that creating a symlink to libudev.so.1 in the same directory (/lib64/ in Fedora 18 64bit) and calling it libudev.so.0 works as well without having to create the shell script, but I would not recommend it since you would be polluting the /lib64/ directory, and it may cause problems in your system.
Solução
Commands that are prefixed by a variable assignment run in a modified environment.
LD_LIBRARY_PATH=/home/omi/nw:$LD_LIBRARY_PATH ./nw $*
is (roughly) equivalent to
OLD_PATH="$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH=/home/omi/nw:$LD_LIBRARY_PATH
./nw $*
LD_LIBRARY_PATH="$OLD_LIBRARY_PATH"
./nw
runs in an environment where LD_LIBRARY_PATH
is set to the given value, but nothing in the current environment is changed.
Your two-line command is equivalent to
LD_LIBRARY_PATH=/home/omi/nw:$LD_LIBRARY_PATH; ./nw $*
(note the semicolon). If LD_LIBRARY_PATH
wasn't already marked for export to the environment, it is simply a local shell variable, and is not inherited by ./nw
when it runs.
Outras dicas
Here's your first script:
LD_LIBRARY_PATH=/home/omi/nw:$LD_LIBRARY_PATH ./nw $*
That command sets LD_LIBRARY_PATH
in the environment of the child process (which runs nw
).
Here's your second script:
LD_LIBRARY_PATH=/home/omi/nw:$LD_LIBRARY_PATH
./nw $*
That script sets the LD_LIBRARY_PATH
shell variable. It doesn't modify the environment of any process, unless the shell is exporting LD_LIBRARY_PATH
, which doesn't happen by default. You need to ask the shell to export LD_LIBRARY_PATH
at least once to make that happen, using the export
command. Example:
export LD_LIBRARY_PATH=/home/omi/nw:$LD_LIBRARY_PATH
./nw $*
You can also export separately from setting the variable, like this:
LD_LIBRARY_PATH=/home/omi/nw:$LD_LIBRARY_PATH
export LD_LIBRARY_PATH
./nw $*