simple bash function does not understand git - bash

I have git installed on my machine using homebrew as you can see below.
$ git --version
git version 1.7.3.4
I am learning bash programming and I have following function in my ~/.bashrc
function gitlab {
CMD= "git --version"
$CMD
}
However when I run gitlab I get following output
$ gitlab
-bash: git --version: command not found
I am using bash on mac.

Your problem is the space after CMD=. This evaluates to CMD=<empty string> "git --version". First, the environment variable CMD is set to an empty string, then the command git --version is called. Notice that due to the "..." the shell really tries to execute a command git --version and not git with argument --version. Simple remove the space between = and " to fix this.

You are running the entire string as a single command. It is possible to have a binary called foo bar (with a space), and you would run it just as you showed.
Edit: What are you actually trying to do? There's no need to store a command in a variable before running it:
gitlab() {git --version}
and
alias gitlab='git --version'
both do the same as you were expecting from the function above. In general, the function solution is recommended above the alias (and you don't need to prefix it with function).

There is a superfluous space after the = when you try to assign the string "git --version" to the CMD variable. The shell think this is an assignation of an empty string to the CMD variable that is only local to the next command. As your command is quoted with ", the shell try to execute a program called git --version. As no such program exist, it fails.
Your function is interpreted almost like the following function (the error is easier to see here):
function() {
CMD=
"git --version"
unset -v CMD
$CMD
}
You should remove the space character to have it interpreted like you intended. However, there are easier way to do the same thing:
function gitlab() {
git --version
}
If you what you wanted was to store the result of the git --version execution to be stored in the CMD variable, you should have done it this way:
function gitlab() {
VERSION="$(git --version)"
echo "$VERSION"
}
Edit: corrected my reply as it was incorrect (error spotted by #DarkDust).

Related

Alias error: using cd command with Git bash

I am trying to add an alias to git to redirect to the project folder, open VS Code and run a local server
my alias:
[alias]
creative = cd e:/work/vero/creative-app/front-end && code . && npm rune serve
problem is when run git creative response is :
expansion of alias 'creative' failed; 'cd' is not a git command
Just prepend a ! to your alias, and it will be interpreted by bash rather than git directly.
From the doc :
As you can tell, Git simply replaces the new command with whatever you
alias it for. However, maybe you want to run an external command,
rather than a Git subcommand. In that case, you start the command with
a ! character.

How to use .bashrc properly and run application?

I'm trying to create an alias for an application for easy access rather than going to the directory and running it.
alias cpanel-run='"$(cd /home/ian/projects/electron/cpanel-linux-x64/)" "$(cpanel)"'
but it only displays
bash: ./cpanel: No such file or directory
Command '' not found, but can be installed with:
sudo apt install bpfcc-tools # version 0.8.0-4, or
sudo apt install mailutils-mh # version 1:3.5-2build1
sudo apt install mmh # version 0.4-2
sudo apt install nmh # version 1.7.1-4
Do you actually need to be in the same directory as the executable? If not, just do this:
alias cpanel-run='/home/ian/projects/electron/cpanel-linux-x64/cpanel'
If you do need to be in the same directory, use this instead:
alias cpanel-run='cd /home/ian/projects/electron/cpanel-linux-x64/ && ./cpanel'
(The && tells the shell to run the first (cd) command, and then run the second only if that succeeds.)
The reason your original version didn't work is that you're using $() inappropriately. What $() does is run its contents as a subprocess collect the output, and use that as part of the command line. So, your version runs the cd command, which successfully changes to the directory, but since it runs as a subprocess it has no effect on your shell or any other process. It also produces no output. Then the other $() tries to run cpanel (is it actually ./cpanel?) in a different subprocess, fails because it's not there (producing the first error message), and also produces no output. Then, based on the (empty) output from those two subprocesses, the shell tries to run the command "" "", which fails because the empty string is not a valid command.
Please refer below, I used to like this, and if you need to run open a terminal and just type kibana or elasticsearch whatever the alias name.
Please note you have to put these lines bottom of the .bashrc file
alias kibana='cd /home/bhanuka/Apps/ELK/kibana-7.5.2-linux-x86_64/bin/ && ./kibana'
alias elasticsearch='cd /home/bhanuka/Apps/ELK/elasticsearch-7.5.2-linux-x86_64/elasticsearch-7.5.2/bin/ && ./elasticsearch'
alias logstash='cd /home/bhanuka/Apps/ELK/logstash-7.5.2/bin/ && ./logstash'
alias filebeat='cd /home/bhanuka/Apps/ELK/filebeat-7.5.2-linux-x86_64/ && ./filebeat -e'

Using !! to access bash history inside a Git alias

I want to create an alias that runs git stash and then executes the command that was before it.
This would be useful when git doesn't allow to run a command with unsaved changes, such as checkout, rebase, etc.
What I've tried:
s = "!git stash && fc -s
s = "!bash -c \"git stash && !!\""
None of the above work. It looks like in the first one git creates a subshell to run this command, as fc outputs no command found.
The second one is similar, but here I explicitly create a subshell and it obviously doesn't work, with no access to the history.
Is there a way around this? It's likely that this could be accomplished with a bash alias, but I'd prefer to do it through a git alias.
It's likely that this could be accomplished with a bash alias,
Yes, this would be simple and robust.
but I'd prefer to do it through a git alias.
Given how ugly and fragile this would be, I doubt it. However, here you go:
First, you need to relay the history. Make your shell write it out to the history file after every command by adding this to your .bashrc:
PROMPT_COMMAND='history -a'
You can then add your git alias. It needs to
run with Bash, since the system sh may not support history expansion
enable history and history expansion
read the history file
use history expansion in a separate parsing unit (e.g. after a linefeed, outside a compound command):
So all in all:
s = "!bash -c 'set -Ho history; history -r ~/.bash_history\ngit stash && !-1'"
Note that it'll run the last command executed regardless of bash instance, so if you use multiple tmux/screen/terminal windows, it won't necessarily run the last command in your current shell.
You can't use a git alias to access the Bash history (or any other shell data for that matter), since the command after the exclamation mark is not run as a subshell. Git is an external command, so all its child processes are also not subshells.
More details
You can confirm this by setting a git alias foo = !echo $$ $BASHPID and comparing it with the current shell:
$ echo $$ $BASHPID
11461 11461
$ git foo
25437
In my case it's not even running Bash. After some testing I think it's running /bin/sh, which is Dash for me since I'm using Ubuntu.

git command with command substitution doesn't return anything

bash: GNU bash, version 4.3.42(4)-release (x86_64-pc-msys)
OS: Windows7
git: git version 2.6.4.windows.1
Without command substitution, directly executing git commands would return correct answers.
$ git write-tree
76cb4719e27c7d77ef396992b3ba90cd98d22fcd
But when I execute some git commands with command substitution, it would return nothing.
$ echo "`git write-tree`"
$ echo "$(git write-tree)"
But the most strange thing is: Only some of git commmands occur this problem, for example: git write-tree, git rev-parse, git var. And other git commands, such as git log, run well.
And some environment is exactly as same as mine, OS, bash and git. But everything works fine.
As a result, I wanna konw whether there's something I need to configure. This thing really confuse me.
That must have been fixed in more recent version of Git for Windows.
Here is what I see with Git 2.18, in a bash session:
vonc#vonca:/mnt/d/git/tests/aa$ echo $(git write-tree)
4b825dc642cb6eb9a060e54bf8d69288fbee4904
vonc#vonca:/mnt/d/git/tests/aa$ echo "$(git write-tree)"
4b825dc642cb6eb9a060e54bf8d69288fbee4904
If the issue is still random, try making the same test using a CMD session with a simplified PATH, and launching the bash from said session.

Using ruby in UNIX shell

I have this program in ruby. I won't explain the whole process, but it gave me in the end a string.
I'd like to use this string in my shell. For now, I can generate it with ruby mysoft.rb
I'd like to use the result's string in a command, for exemple, when I commit with git, with something like this
git commit -m "$generated_string"
I would that the file was install on the computer and be usable by him. With a single command, he could have the generated string, from any directory, like a "normal" command like "ls" for exemple.
I have no idea how to do that ? Should I do a Gem ? Or something else. I'm new in Ruby, so, pretty confused.
Thanks a lot.
You are looking for shell command substitution; the syntax depends on which shell you are using. For example, if using bash or csh:
$ git commit -m `ruby mysoft.rb`
The following syntax does the same thing but in bash only:
$ git commit -m $(ruby mysoft.rb)
Change the first line of your program to this:
#!/usr/bin/env ruby
This line tells the shell that ruby should be used to execute this script by default.
Before you can run the script however you need to add the executable bit to the file:
> chmod gou+x mysoft.rb
Now you can type on the command line directly:
> ./mysoft.rb
And ruby will run your program.
If you want to make the command globally available on your machine, for example with the name mysoft, then you need to do this:
> sudo cp mysoft.rb /usr/bin/mysoft
This will install the program in the bin directory of the system. After this whenever you type mysoft anywhere on the machine, your program will run.

Resources