LD_PRELOAD in rlwrap? - linux

When I do something in my script like
rlwrap -f words.txt LD_PRELOAD=mylib.so command "$#"
I always get something like
rlwrap: error: cannot execute LD_PRELOAD=mylib.so no such file or directory
Even though that file totally exists and removing rlwrap would work just fine.
How do I put LD_PRELOAD in rlwrap? basically I want to make mylib.so apply to my 'command' only.
I did try putting LD_PRELOAD=mylib.so in from of rlwrap, it runs, but LD_PRELOAD didn't apply to command as I wished.

You can wrap the command in a shell:
rlwrap -f words.txt bash -c 'LD_PRELOAD=mylib.so command "$#"' - "$#"

Related

bash auto complete binary file which is not in PATH

I'm trying to make a custom bash auto completion script on my CLI package.
When I install my package like below, then my command is installed in $PATH (/usr/local/bin),
$ ./configure
$ make
$ sudo make install
so complete -o filenames -F _mycommand mycommand in my bash-autocomplete.sh works properly.
(Because command mycommand is in $PATH (/usr/local/bin)
However, when I install my package locally, and then try to execute binary file from installed location like below,
$ ./configure --prefix=$HOME/usr
$ make
$ make install
complete -o filenames -F _mycommand mycommand doesn't work because OS don't know the location of mycommand.
$ ~/uftrace$ $HOME/usr/bin/mycommand [TAB]
Command 'command' not found,
My question is this:
How can I make bash completion feature with my local binary file? (which is not in PATH)
Can I do this by fixing Makefile or configure or bash-autocomplete.sh?
+
Install the package locally, and than add PATH is not an option because I want to make this bash auto-completion feature regardless of installation location. I want to this feature work at installation point.
From the documentation, that's not possible unless using an "intelligent" completion loader:
First, the command name is identified. [...]
If the command word is a full pathname, a compspec for the full pathname is
searched for first. If no compspec is found for the full pathname, an
attempt is made to find a compspec for the portion following the final
slash.
I put an emphasis (or bold) on the part that should apply: bash will be able to complete the full path (eg: /usr/mycommand or even ./mycommand) but it won't be able to resolve mycommand unless it is found in the PATH and where some completion does the trick.
At last resort, you could register a completion loader which may for example look at the command (using ${1##*/} to get the basename):
_completion_loader() {
if [[ "${1}" == mycommand || "${1##*/}" == mycommand ]]; then
complete -o filenames -F _mycommand "$1"
return 124
fi
return 1 #
}
complete -D -F _completion_loader -o bashdefault -o default
I would not do that on Linux, due to chance of bash-completion begin already there and providing completion by itself: you could check bash-completion as they may perhaps have a way to handle your completion, for example by saving in /etc/bash_completion.d/<yourcommand>.bash.

STDIN from Makefile with make run command

I have a program in which I'm trying to invoke the following command:
make run {FILE} e.g filename.txt
How can I create my Makefile so it can execute this program and accept any filename through STDIN.
My Makefile looks like the following:
run:
python execute.py --filename {ANY FILENAME}
The arguments to make are targets. There's no special relationship between run and {FILE} in your initial example. If you want to force the run prefix, it'll have to be part of the target name, instead of space separated:
run-%:
python execute.py --filename $*

bash prefix output with current directory

After a couple of hours of flailing, I give up.
I have a long-running build script in a bash function, let's call it "Build":
function Build( ) {
cd /plugins
make
cd /acc
make
}
... and I would like the output from the script to be prefixed on each line with the current directory, something like:
/plugins: configure: checking for gcc
/plugins/inner: making inner modules
...
/acc: configure: checking for speed of strstr.
/acc/misc making misc pieces
.... and so on. There are dozens of "cd"s in the scripts so I don't want to change each and every one. Tried various combinations of piping to awk and trap DEBUG, but no joy.
Any ideas?
You can try overriding built-in cd with function like:
cd(){ builtin cd "$#"; pwd }
Or if you really want to instrument every command, then:
trap "eval 'echo -n $PWD:'" DEBUG
Or to trace really every chdir syscall even inside the child processes of the actual bash script (e.g. make), you can use strace:
strace -f -e trace=chdir bash build.sh

Can make shell run interactively along with --command option

I'm using GNU bash that is installed as git bash. On startup I need to change directory, so I'm doing it like this:
"C:\Program Files\Git\bin\sh.exe" --rcfile "./cd.sh"
Where cd.sh just contains cd /d/ command. Everything works fine here. Now I'm trying to get rid of cd.sh file and pass command to the shell as a parameter yet I want it to remain interactive, so I'm doing like this:
"C:\Program Files\Git\bin\sh.exe" -ic "cd /d"
It executes the command (tested with echo command) but then exits. Why doesn't it stay interactive?
From man bash:
An interactive shell is one started without non-option arguments and without the -c option ...
From man dash:
If no args are present and if the standard input of the shell is connected to a terminal (or if the -i flag is set), and the -c option is not present, the shell is considered an interactive shell.

coloring terminal with shell script

Someone can explain me why when I copy and paste the following command in the terminal it displays the colorful test correctly, but when I run it via sh myscript.sh it does not display the colored text?
blue='\e[1;34m'
NC='\e[0m'
echo -e "${blue}Test${NC}"
EDIT
Sudo is not the problem. If I copy the above and paste directly into the terminal, everything works. If you run through file, sh myscript.sh not work
Probably because sh isn't bash on your system.
$ file /bin/sh
/bin/sh: symbolic link to `dash'
Try
bash myscript.sh
Your interactive shell seems to be GNU Bash, while sh is a generic POSIX shell, which actually may be dash, busybox sh or something else. The problem is that neither -e option for echo nor \e are POSIX-compliant.
But you can easily use printf instead of echo -e (do not forget to explicitly specify newline character \n) and \033 instead of \e:
blue='\033[1;34m'
NC='\033[0m'
printf "${blue}%s${NC}\n" 'Test'
Or, of course, you can just use bash (as Elliott Frisch suggested) if you are sure that it would be available on target system.
Also I should point out, that what you done is not right way to run shell scripts at all. If you’re writing a standalone script, then you’d better to use hashbang and set execution bit to file.
$ cat myscript
#!/bin/sh
blue='\033[1;34m'
NC='\033[0m'
printf "${blue}%s${NC}\n" 'Test'
$ chmod +x myscript
$ ./myscript
But if you’re writing a command sequence (a macros, if you will) for interactive shell, there is source (or simply .) command:
$ source myscript
(Then all of above about POSIX-compliance does not matter of course.)

Resources