Bash complains "have not a command" when login - linux

I have a file named "upstart" in /etc/bash_completion.d/ with the following content:
# bash-completion for the upstart event-based init replacement
# (http://upstart.ubuntu.com / https://launchpad.net/upstart)
#
# We don't provide completion for 'init' itself for obvious reasons.
have initctl &&
_upstart_jobs()
{
initctl list|awk '{print $1}'|sort -u
} &&
The confusing part is the line have initctl &&, I have configured bash to source
all files in /etc/bash_completion.d/ and every time I login it complains
that command have cannot be found. What is that line for?

Short Answer: maybe you should install bash-completion package.
In general, you don't need to manually source the files in /etc/bash_completion.d/.
It is automatically imported by bash_completion script.
bash_completion script is called by /etc/bash.bashrc (at least for Ubuntu and Arch Linux), which would be called by default.
In Ubuntu, bash_completion script is in bash-completion package and placed in /etc/bash_completion
In Arch Linux, bash_completion script is in bash-completion package and placed in /usr/share/bash-completion/bash_completion
Therefore, installing bash-completion script would help if you are using Ubuntu or Arch Linux.

Related

.Deb package postinst file not appending data to ~/.bashrc

I have this very simple postinst file for a .Deb package:
#!/bin/sh
echo 'alias command_pandora="sudo /usr/local/bin/pandora"' >> ~/.bashrc
echo 'Pandora Storage Server Installation complete.'
When I run it I even get the 'Pandora Storage Server Installation complete.' message, but nothing is appended to ~/.bashrc; nevertheless when I run this command alone in the terminal:
echo 'alias command_pandora="sudo /usr/local/bin/pandora"' >> ~/.bashrc
It does work. I already tried modifying the file permisions for ~/.bashrc but still get the same result. I also tried running a separate script with the same content and running it and it also works, so it seems to be related to dpkg.
Why is the content not being appended?
The postinst script runs as root. Package installation is a system installation utility; it should absolutely not modify users' private files, including those of root.
Tangentially, defining an alias seems like the wrong solution to your problem. Generally, prefer functions or shell scripts over aliases.
If the tool requires privileged access through sudo, perhaps refactor it to run itself with sudo (maybe with a check to only do this when it is connected to a terminal, to prevent it from hanging when run unattended).
Or, simply, include /usr/bin/command_pandora in the package with the following contents:
#!/bin/sh
exec sudo /usr/local/bin/pandora "$#"
(Marginally, I suppose it could add something to /etc/skel/.bashrc but this will only create a new alias for users which are created after this change, or users whose .bashrc presciently run source /etc/skel/.bashrc. I don't think that's a good idea, either.)

shebang under linux does not split arguments

I have kotlin script (but it can be any Linux command with arguments) for example:
#!/usr/bin/env kotlinc -script
println("hello world")
When I run it in Ubuntu I get:
/usr/bin/env: ‘kotlinc -script’: No such file or directory
but when I run in command line:
/usr/bin/env kotlinc -script
It works. It is no problem with finding path because script:
#!/usr/bin/env kotlinc
println("hello world")
works
For some reason under Ubuntu "#!/usr/bin/env kotlinc -script" treats "kotlinc -script" as single argument. But only in shell script header.
I need explicitly to run my script "#!/usr/bin/env kotlinc -script" because I want it to run properly on other distributions end environments where "kotlin" is in $PATH.
Is there a bug in Ubuntu coreutils or sth? Is there a way to fix it?
On Linux, you can't pass more than one argument via the shebang line. All arguments will be passed as a single string to the executable:
#!/bin/foo -a -b -c
will pass one option "-a -b -c" to /bin/foo, plus the contents of the file. Like if you would call:
/bin/foo '-a -b -c' contents-of-file.txt
The behaviour should be the same on most unix derivates nowadays, but it can differ, I haven't tested them all :)
It's hard to find proper documentation for this, the best I could quickly find was this: https://www.in-ulm.de/~mascheck/various/shebang/#splitting
As a workaround you would normally create a shell wrapper:
#!/bin/bash
exec kotlin --arg1 --arg2 ... /path/to/kotlin-script
Check your coreutils version:
apt-cache policy coreutils
Starting with coreutils 8.30 you will be able to use:
#!/usr/bin/env -S command arg1 arg2 ...
You may want to upgrade your coreutils
For me the solution was to install kotlin, since I did not yet have installed it and just downloaded https://github.com/bernaferrari/GradleKotlinConverter
and thought it should work.
sudo snap install kotlin --classic

bash changing directory when started

I have both Bash on Ubuntu on Windows and Cygwin bash installed on my machine, and both are setup to have the same ~ folder (via /mnt/c/source and /cygdrive/c/source respectively).
When I start Ubuntu's bash prompt via bash --login -i (or just bash --login) from any directory, I get a prompt running from within that directory; however, when I start Cygwin's bash via the same command, the current directory is overridden, and the prompt is always at ~. See the screenshots for a simple example.
My user directory's .bashrc and .bash_profile are of course the same, as both are using the same user directory. I've looked into Cygwin's /etc/bash.bashrc and there doesn't seem to be anything there to change my current directory, and there aren't any other relevant files in /etc.
What could be causing Cygwin's bash to change directory?
you just add a command "cd /dir_you_want" at the bottom of ~/.bashrc in cygwin
I've figured it out, so in case anyone runs into the same issue:
There's one file I neglected to look into, because I didn't know it exists, /etc/profile. In Cygwin, by default it has the following section in it:
# Make sure we start in home unless invoked by CHERE
if [ ! -z "${CHERE_INVOKING}" ]; then
unset CHERE_INVOKING
else
cd "${HOME}" || echo "WARNING: Failed attempt to cd into ${HOME}!"
fi
Disabling that solves the issue of course.

Bash: Invalidated commands

I've incurred a worrisome issue with my bash shell. I was editing my bash_profile and accidentally exported an incomplete command (export PATH=/usr/local/bin). After I had reloaded my terminal, nearly all of my bash commands fail to work properly. When I try to run any one of them, the errors state: command not found.
How do I fix this? Is there an alternate way to open or find my bash_profile?
I would appreciate any immediate input I can get on this issue. Thank you in advance.
You can execute commands if you can give the directory name. Almost all the basic Unix commands are under the /bin or /usr/bin directory. For example, /bin/mv.
Fortunately, builtin commands are still recognizable.
Move your .bash_profile and .bashrc file out of the way for now, and see what the system default is.
You can manually edit your PATH on the command line to:
$ PATH="/bin:/usr/bin"
$ cd
$ mv .bash_profile .bash_profile.bak
$ mv .bashrc .bashrc.bak
$ mv .profile .profile.bak
$ mv .bash_login .bash_login.bak
NOTE: Some of these mv command may fail simply because that particular file may not exist.
which will give you access to most of the basic Unix commands. Or you can specify the commands with their full directory names:
$ PATH="/bin:/usr/bin"
$ cd
$ /bin/mv .bash_profile .bash_profile.bak
$ /bin/mv .bashrc .bashrc.bak
$ /bin/mv .profile .profile.bak
$ /bin/mv .bash_login .bash_login.bak
Now, log in again and see what your default $PATH is set to. This is set by the /etc/profile. You might find that's just fine, and remove setting PATH in your startup script.
The standard for PATH is something like this:
/usr/share/bin or /usr/local/bin - These contain non-standard Unix/Linux commands. For example, if you install Maven on your system, the mvn command will usually be located in one of these directories (maybe as a symbolic link). This directory is a place where commands not found in the /bin and /usr/bin directory are stored. This directory is first, so you can replace the version which came with your system with more recent versions. For example, I might have VIM 6.4 installed, but I want to use version 7.3 instead.
/bin:/usr/bin - The standard directories where 99% of the Unix commands live.
$HOME/bin - These are executables you wrote -- either scripts or binaries. This is at the end of the PATH list because it makes sure that you don't accidentally execute the wrong version of the command. Imagine if some joker wrote a shell script called cp that executed /bin/rm instead and placed it in your $HOME/bin directory.
Other directories you'll see may include /sbin/ and /usr/sbin which are administrator commands (ping and ifconfig are sometimes in one of these directories.) /opt/bin/X11 (or wherever the X11 binaries are stored). Sometimes other commands will futz around with your PATH, for example Perlbrew.
#fedorqui's comment provides a quick fix.
The OP could also have used the following to quickly get to a shell with default values for $PATH:
To create a bash shell with a pristine default environment:
without running profile/initialization scripts
without inheriting any environment variables from the current shell
run:
/usr/bin/env -i bash --norc
Note:
Due to use of env's -i option, many environment variables that are normally set will NOT be set in the resulting shell , such as USER, HOME and LANG.
Similarly, the $PATH value you'll get is presumably one hard-coded into bash itself, but it should provide access to at least the standard utilities.
--norc suppresses loading of ~/.bashrc, which normally happens by default for interactive non-login bash shells (bash also supports the --noprofile option to suppress loading of /etc/profile and ~/.bash_profile, but it doesn't apply here, since the shell created is a non-login shell).
If env is in the current shell's $PATH, env -i bash --norc will do.
env is in /usr/bin/ on at least Linux and on FreeBSD/OSX, probably also on other platforms.

how to make nvm automatically sourced upon login

I am using nvm to manage the node version.
I like to make nvm sourced upon login, so I dont have to do it manually everytime I login.
in my user home directory, there's a .bashrc file. I appended following two lines to the end of the file. then restart my mac os. after I login, nvm is not sourced. I have to manually run them again. coudln't figure out whats wrong. please help.
. ~/nvm/nvm.sh
nvm use 0.8.20
You need to put into your .bash_profile this line
[[ -s $HOME/.nvm/nvm.sh ]] && . $HOME/.nvm/nvm.sh
Source the file (source ~/.bash_profile) or reopen the shell and then in the shell execute:
$ nvm alias default <version>
That would load node in any new shell you open.
Using .nvmrc file
It turns out that creating a .nvmrc file in your home directory is enough. It is loaded automatically when you open the terminal.
To create the .nvmrc file with the version we want to run (0.12.2) do this:
echo '0.12.2' > ~/.nvmrc
If that for some reason doesn't work, force load the nvm from your .bashrc
But only if you're running in interactive mode.
Add the command to run nvm use 0.12.2 (or any other version you'd like to run) if the shell is launched in interactive mode to the end of .bashrc.
echo '[[ $- == *i* ]] && nvm use 0.12.2' >> ~/.bashrc
Boom, done! :)
For Mac at least, open your .profile file, and add this line in
[[ -s $HOME/.nvm/nvm.sh ]] && source "$HOME/.nvm/nvm.sh"
# Load NVM into a shell session *as a function*
Done, bingo bango, GG.
Please use the official website carefully as I used
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | zsh from https://github.com/nvm-sh/nvm and it automatically does my work from installing to load automatically setup.

Resources