How to convert export line from bash to fish? - fish

I have a bash profile as to add a ':' if LIB exist, skip the ':' when LIB not defined.
export LIB="{LIB:-}${LIB:+:}/example/lib"
If run in fish, it will show
${ is not a valid variable in fish.
Any trick to convert this line to fish?

In short: In this simple case, try
set -gx LIB (string join : -- $LIB /example/lib)
This will construct a string with string join - if $LIB was set, it'll add it and a : before "/example/lib", if it wasn't it won't.
The underlying thing here is that fish doesn't have these variable expansion shortcuts like ${foo:+-/%#} and such.
The intention here is to do something similar to what you would do with $PATH - "add :/foo if $PATH is set, or set it to /foo otherwise".
For $PATH, because it is a list in fish (as it is a PATH variable - these are automatically joined/split with ":"), you would simply do
set -gx PATH $PATH /foo
You could define your variable $LIB as a path variable like
set -gx --path LIB $LIB /example/lib
and fish would do the same for it. Now inside fish it would be accessible as a list so you could use $LIB[1] to get the first element, and outside of fish it would be available in the colon-delimited form so applications know what to do with it.
But if you don't want to do that, see the string join method above.

Related

Set PATH for one command in fish

In bash in order to update PATH just for one command I can do:
env PATH=/my/path:$PATH mycommand.sh
What is the equivalent syntax for fish? I have tried many variations with spaces or colons, and none work.
In fish, $PATH is a list not a colon-separated string. You need to convert it to the expected format first:
env PATH=(string join ":" /my/path $PATH) mycommand.sh

How do I update a datastore variable from inside a bash variable?

I have a variable set in a bbclass file like:
#some-class.bbclass
PROC ??= ""
In a recipe inheriting the class, I have a bash function where I modify that variable and immediately read its value. But, the value never gets updated.
#some-bb-file.bb
inherit some-class.bbclass
some_configure() {
PROC=$(grep -r "Processor.*${cpu_id}" ... something)
bbnote "PROC is ${PROC}"
}
I always get "PROC is " in the logs. I have tried printing the output of "(grep -r "Processor.*${cpu_id}" ... something)" and it returns a valid string. Can someone please tell me what I am missing?
Usage of bitbake and shell variables in your code snippet is mixed. Your bbnote line should omit the curly braces to access the shell variable, i.e.:
bbnote "PROC is $PROC"
Explanation: The bitbake and local shell variables are different. If you are in the shell function, then ${PROC} is the variable defined in some-class.bbclass. That variable isn't redefined when you do PROC="foo". If you use $PROC, the shell variable defined by PROC="foo" is used.
And your question in the title - I'm not sure if it is possible to update datastore variable from shell. You can get and set datastore variables in Python functions (using d.getVar and d.setVar).
Datastore variables can be read from Shell using :
${#d.getVar('PROC')}
In case you have to use others operations, then switch to Python
I guess you missed backticks
PROC=`grep -r "Processor.*${cpu_id}" ... something`
bbnote "PROC is ${PROC}"

How to make setenv to an output of a perl script

I wrote a perl script that prints a path to a very specific file. I want to define a personal environment variables (by using setenv in .aliases file) that gives the output of this script.
For example, let's say that the file "myscript.pl" prints the path "/home/files/reports/file". Let's call the variable (that I want to define in .aliases file) 'myoutput'. I want that when I type "most $myoutput" in Unix, this file will be opened by most, and when I type "echo $myoutput", Unix will print the path.
How can I define a personal variable which value is determined by a script?
If you use bash, you can put the following to your .bashrc:
export myoutput=$(perl /path/to/myscript.pl)
For tcsh, use .cshrc instead, and modify the line to
setenv myoutput `perl /path/to/myscript.pl`
You need to start a new session to make the variable exist.
myoutput=$(perl myscript.pl)
When your script prints more, select the correct line:
myoutput=$(perl myscript.pl | grep /home)

Running a script in bash

I have a script in one of my application folders.Usually I just cd into that locatin in Unix box and run the script e.g.
UNIX> cd My\Folder\
My\Folder> MyScript
This prints the required result.
I am not sure how do I do this in Bash script.I have done the following
#!/bin/bash
mydir=My\Folder\
cd $mydir
echo $(pwd)
This basically puts me in the right folder to run the required script . But I am not sure how to run the script in the code?
If you can call MyScript (as opposed to ./MyScript), obviously the current directory (".") is part of your PATH. (Which, by the way, isn't a good idea.)
That means you can call MyScript in your script just like that:
#!/bin/bash
mydir=My/Folder/
cd $mydir
echo $(pwd)
MyScript
As I said, ./MyScript would be better (not as ambiguous). See Michael Wild's comment about directory separators.
Generally speaking, Bash considers everything that does not resolve to a builtin keyword (like if, while, do etc.) as a call to an executable or script (*) located somewhere in your PATH. It will check each directory in the PATH, in turn, for a so-named executable / script, and execute the first one it finds (which might or might not be the MyScript you are intending to run). That's why specifying that you mean the very MyScript in this directory (./) is the better choice.
(*): Unless, of course, there is a function of that name defined.
#!/bin/bash
mydir=My/Folder/
cd $mydir
echo $(pwd)
MyScript
I would rather put the name in quotes. This makes it easier to read and save against mistakes.
#!/bin/bash
mydir="My Folder"
cd "$mydir"
echo $(pwd)
./MyScript
Your nickname says it all ;-)
When a command is entered at the prompt that doesn't contain a /, Bash first checks whether it is a alias or a function. Then it checks whether it is a built-in command, and only then it starts searching on the PATH. This is a shell variable that contains a list of directories to search for commands. It appears that in your case . (i.e. the current directory) is in the PATH, which is generally considered to be a pretty bad idea.
If the command contains a /, no look-up in the PATH is performed. Instead an exact match is required. If starting with a / it is an absolute path, and the file must exist. Otherwise it is a relative path, and the file must exist relative to the current working directory.
So, you have two acceptable options:
Put your script in some directory that is on your PATH. Alternatively, add the directory containing the script to the PATH variable.
Use an absolute or relative path to invoke your script.

How do we replace PATH in all the files with an env variable

I have around 230 files which are *.pl , *.txt and some are *.conf files which has a default path set to the current environment say /home/AD/USR/perl/5.8.0/bin/perl. I need to replace "/home/AD/USR" with an environment variable ${USR_PATH}. The files I want to modify are in subdirectories. Which means my script should find e.g find .|xargs grep -l "/home/AD/USR" all the files and then replace the string.
OLD: /home/AD/USR/perl/5.8.0/bin/perl
New : ${USR_PATH}/perl/5.8.0/bin/perl
Can some one give me a clue how do I do that?
Shell : /bin/bash
Env : Linux x86_64
If you replace part of a string with ${USR_PATH} you will refer to the perl variable $USR_PATH, not the environment variable, which is in perl referred to as $ENV{USR_PATH}.
perl -pi.bak -we 's#/home/AD/USR(?=/perl/5.8.0/bin/perl)#\$ENV{USR_PATH}#g'
*.pl *.txt *.conf
Using the lookahead will save you the trouble of replacing the rest of the path afterwards.
I assume you want to replace it with the literal value. If you want to replace it with the actual value in the environment variable, just remove the backslash in front of $ENV.
While using an environment variable seems handy and all, it will reduce your scripts portability. Why not use a configuration file? If you had done that from the start, you wouldn't be having this trouble. Search CPAN for a nice module.
perl -i -pe 's|/home/AD/USR/perl/5.8.0/bin/perl|\${USR_PATH}/perl/5.8.0/bin/perl|' <your files>