fishshell alias without replacing command - fish

I am having a trial of fishshell, currently using zsh
When I set an alias in fishshell config, e.g.
alias aa="abc -d -e -f"
Fishshell replaces the command with the actual command while I am typing the command. It is possibile to config it to work seamlessly without replacing the command?

What you're describing is abbreviations, not aliases. Abbreviations are commands that expand as you type them.
Running a command like you described:
alias aa="abc -d -e -f"
will indeed set an alias that will not expand in-line.

Related

Replace string with $ from makefile with sed

I am trying to replace ${dbPassword} in a property file with a password including $ signs.
My command is the following, but I have no idea how to replace this properly.
run: #cat $(FILE_PATH) | sed -i .bak 's/$${dbPassword}/$(VARIABLE_WITH_PWD)/g' $(FILE_PATH)
Let's say my dbPassword is: 123$456$789
With this, I am getting the result: 123${dbPassword}456${dbPassword}789
Three problems:
Target and recipe on the same line. The recipe must be on the next line, indented with a hard tab.
You pass $(FILE_PATH) on stdin, and as a file argument to sed. Remove the cat pipe.
Shell variables (as opposed to make variables) are not substituted inside single quotes.
So you might want to try this instead:
.PHONY: run
run:
sed -i .bak "s/$${dbPassword}/$(VARIABLE_WITH_PWD)/g" $(FILE_PATH)
This assumes you have an environment variable, dbPassword and exported it prior to running make. If that is not the case, please provide your complete makefile.
I also have removed the # so you actually see what command make is executing. There's no point in wearing a blindfold while debugging your makefile.

Multiple mongo commands in kubernetes not working

I am attempting to automate the following series of commands which work correctly into a BASH script:
kubectl exec -it mongo-pod -- bash
mongo DBNAME
db.auth("theUser", "thePw")
db.theCollection.find()
The script I am using is as follows:
#!/bin/bash
kubectl exec -it mongo-pod -- bash -c "mongo DBNAME && /
db.auth("theUser", "thePw") && /
db.theCollection.find()"
I have tried the following:
Executing multiple commands( or from a shell script) in a kubernetes pod
but any commands that are added after the first using & or && are not executed. For example just using "mongo DBNAME" correctly opens the prompt and sets it to the correct db, but adding any other command with && causes all commands to fail with the following:
bash: -c line 0: syntax error near unexpected token 'theUser'
All of the comments are spot on, but at least two things I have the highest confidence I have the answer to:
First, you have the line continuation character wrong; it should be \ and not /. It actually wouldn't even be required if you switched bash into "exit on error" mode, with
kubectl exec -it mongo-pod -- bash -ec "mongo DBNAME
echo 'this command only runs if mongo exits a-ok'
exit 1
and this never will run
"
However, the other mistake is around the quoting characters used: if you have bash -c " then you must either use the single-quote for the interior string literals, or escape them with \". You can actually see what I'm talking about by looking at the syntax highlighting of the shell snippet in your question. Observe that the string literal is red, but then the text theUser as well as thePw are both black -- that's because they are outside the string literal since the string stopped at the first " it encountered -- the one present in db.auth("
It is almost always the case that you'll want to use single quotes when invoking bash remotely like that, for several reasons but the most relevant is that you can then use db.auth("something") without having to unnecessarily escape the double quotes.
Since mongo (like many interpreters such a node and python) wants you to either type in it interactively, provide the input on its "standard input", or give it a local file containing commands, you will want to change the invocation to one of those strategies depending on your needs.
A very convenient way of redirecting standard input without having to use echo or printf and its associated quoting hell is to use what are called "here documents" (abbreviated "heredocs") in bash:
kubectl exec -it mongo-pod -- bash -ec 'mongo DBNAME<<"FOO"
db.auth("theUser", "thePw")
printjson(db.theCollection.find())
FOO
'
That causes bash to transmit almost all characters between the two "heredoc delimiters" to the standard input of the command. If you quote the delimiter, as I have with the [arbitrary] word FOO, then the contents are not subject to variable expansion, command interpolation, etc, which can be one more mechanism to avoid backtick and dollarsign weirdness.

Why Parameter Expansion is not working? [duplicate]

#!/bin/bash
jobname="job_201312161447_0003"
jobname_pre=${jobname:0:16}
jobname_post=${jobname:17}
This bash script gives me Bad substitution error on ubuntu. Any help will be highly appreciated.
The default shell (/bin/sh) under Ubuntu points to dash, not bash.
me#pc:~$ readlink -f $(which sh)
/bin/dash
So if you chmod +x your_script_file.sh and then run it with ./your_script_file.sh, or if you run it with bash your_script_file.sh, it should work fine.
Running it with sh your_script_file.sh will not work because the hashbang line will be ignored and the script will be interpreted by dash, which does not support that string substitution syntax.
I had the same problem. Make sure your script didnt have
#!/bin/sh
at the top of your script. Instead, you should add
#!/bin/bash
For others that arrive here, this exact message will also appear when using the env variable syntax for commands, for example ${which sh} instead of the correct $(which sh)
Your script syntax is valid bash and good.
Possible causes for the failure:
Your bash is not really bash but ksh or some other shell which doesn't understand bash's parameter substitution. Because your script looks fine and works with bash.
Do ls -l /bin/bash and check it's really bash and not sym-linked to some other shell.
If you do have bash on your system, then you may be executing your script the wrong way like: ksh script.sh or sh script.sh (and your default shell is not bash). Since you have proper shebang, if you have bash ./script.sh or bash ./script.sh should be fine.
Try running the script explicitly using bash command rather than just executing it as executable.
Also, make sure you don't have an empty string for the first line of your script.
i.e. make sure #!/bin/bash is the very first line of your script.
Not relevant to your example, but you can also get the Bad substitution error in Bash for any substitution syntax that Bash does not recognize. This could be:
Stray whitespace. E.g. bash -c '${x }'
A typo. E.g. bash -c '${x;-}'
A feature that was added in a later Bash version. E.g. bash -c '${x#Q}' before Bash 4.4.
If you have multiple substitutions in the same expression, Bash may not be very helpful in pinpointing the problematic expression. E.g.:
$ bash -c '"${x } multiline string
$y"'
bash: line 1: ${x } multiline string
$y: bad substitution
Both - bash or dash - work, but the syntax needs to be:
FILENAME=/my/complex/path/name.ext
NEWNAME=${FILENAME%ext}new
I was adding a dollar sign twice in an expression with curly braces in bash:
cp -r $PROJECT_NAME ${$PROJECT_NAME}2
instead of
cp -r $PROJECT_NAME ${PROJECT_NAME}2
I have found that this issue is either caused by the marked answer or you have a line or space before the bash declaration
Looks like "+x" causes problems:
root#raspi1:~# cat > /tmp/btest
#!/bin/bash
jobname="job_201312161447_0003"
jobname_pre=${jobname:0:16}
jobname_post=${jobname:17}
root#raspi1:~# chmod +x /tmp/btest
root#raspi1:~# /tmp/btest
root#raspi1:~# sh -x /tmp/btest
+ jobname=job_201312161447_0003
/tmp/btest: 4: /tmp/btest: Bad substitution
in my case (under ubuntu 18.04), I have mixed $( ${} ) that works fine:
BACKUPED_NB=$(ls ${HOST_BACKUP_DIR}*${CONTAINER_NAME}.backup.sql.gz | wc --lines)
full example here.
I used #!bin/bash as well tried all approaches like no line before or after #!bin/bash.
Then also tried using +x but still didn't work.
Finally i tried running the script ./script.sh it worked fine.
#!/bin/bash
jobname="job_201312161447_0003"
jobname_post=${jobname:17}
root#ip-10-2-250-36:/home/bitnami/python-module/workflow_scripts# sh jaru.sh
jaru.sh: 3: jaru.sh: Bad substitution
root#ip-10-2-250-36:/home/bitnami/python-module/workflow_scripts# ./jaru.sh
root#ip-10-2-250-36:/home/bitnami/python-module/workflow_scripts#

same aliases and functions for user and root in fish shell

How can I make aliases defined in ~/.config/fish/config.fish and functions defined in ~/.config/fish/functions available for the root user as well?
symlinking to /root/.config/fish didn't do the job. Furthermore, I'd also like to be able to use my functions and aliases via sudo, which is currently not working as well.
How do you guys do that?
I don't have a solution for the first problem (I don't have any functions that are useful for the root user), but the second one (functions not working as an argument for sudo) can be solved with a wrapper function:
function sudo
if functions -q $argv[1]
set argv fish -c "$argv"
end
command sudo $argv
end
The issue is of course that sudo is an external command (usually at /usr/bin/sudo) that cannot know about fish internals like function definitions. So this wrapper will call fish if you give it a function name. Of course, since this launches a new fish session, some things, like cd will not be useful because it won't alter the state of the main fish session.
I use a symlink to my config.fish and works perfectly. Have you checked the permissions?
777 lrwxrwxrwx 1 root root 35 Dez 21 2015 /root/.config/fish/config.fish -> /home/lara/.config/fish/config.fish
In newer versions you can also use the directory /etc/fish/ for system-wide configuration
The problem with sudo I solved with an alias:
# -E just preserv env. It's not really
# necessary, but may be useful.
function sudo; command sudo -sE $argv; end
from sudo man page:
-s, --shell
Run the shell specified by the SHELL environment variable if it is set or the shell specified by the invoking user's
password database entry. If a command is specified, it is passed to
the shell for execution via
the shell's -c option. If no command is specified, an interactive shell is executed.
Old question that I came across while attempting to do the same thing myself.
Neither existing solution from #faho or #LaraMaia solves the first part of the question, which is really what I needed for my use-case. Both solutions only handled functions that are defined in ~/.config/fish/functions. In-memory functions and aliases that have not been "saved" do not work.
So here's a version that does work for aliases/in-memory functions:
function sudo
if functions -q -- "$argv[1]"
set cmdline (
for arg in $argv
printf "\"%s\" " $arg
end
)
set -x function_src (string join "\n" (string escape --style=var (functions "$argv[1]")))
set argv fish -c 'string unescape --style=var (string split "\n" $function_src) | source; '$cmdline
command sudo -E $argv
else
command sudo $argv
end
end
Commented and slightly expanded version at this Gist.

Strange sed command

I was trying to install docker in Ubuntu, and following the instructions I have come across a very strange sed command which I do not understand (this seems to be used to set-up bash autocompletion for docker):
sudo sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io
What is that command doing? The -i command means in-place editing, but what does the $acomplete -F _docker docker mean? The $ is matching the last line, but what is it doing? I do not even recognize any sed command there! For example, a substitution command would look like:
$s/in/out/
Could somebody explain that expression for me?
It appends complete -F _docker docker to the file.
From sed's manual:
a \
text Append text, which has each embedded newline preceded by a backslash.