Use "perl6" command with Git Bash on windows - windows

Using Windows, I installed Rakudo Star and Git and ensured that C:\rakudo\bin and C:\rakudo\share\perl6\site\bin are in my Path environment variable.
Now, typing perl6 inside Git Bash afterwards gives the command not found error, while the command does work inside powershell and cmd. Typing echo $PATH inside Git Bash confirms again that the folders above are in my path variable here as well.
How can I get the perl6 command working inside Git Bash?
Note: Using moar (moar.exe) which resides in the same folder as perl6 works as well in Git Bash. Also hitting Tab show the autocomplete suggestion for moar, it does not do that for perl6.

Bash doesn't run Windows batch files, so you'll have to work around that.
An easy solution might be to add something like this you your .bashrc:
alias perl6='cmd /c perl6.bat'
Alternatively, you can convert perl6.bat to a shell script and put it somewhere in your $PATH.
I use the following:
#!/bin/sh
PATH=/cygdrive/c/rakudo/bin:/cygdrive/c/rakudo/share/perl6/site/bin:$PATH
unset HOME
moar --execname="$0" \
--libpath='C:\rakudo\share\nqp\lib' \
--libpath='C:\rakudo\share\perl6\lib' \
--libpath='C:\rakudo\share\perl6\runtime' \
'C:\rakudo\share\perl6\runtime\perl6.moarvm' \
"$#"
This is using Cygwin; you may need to adapt it a bit for Git bash (I don't know, no experience with it).
Alternatively, if you're using Windows 10, I can recommend installing WSL, and using perl6 in a WSL bash prompt instead. This runs much smoother for me than the Windows version under Cygwin.

I tried to install perl6 from the link you provided and I can confirm the same behavior on Cygwin on Windows 10.
If I type in the Cygwin terminal window:
$ perl6
-bash: perl6: command not found
$ echo $PATH
/usr/local/bin:/usr/bin:/cygdrive/c/WINDOWS/system32:/cygdrive/c/WINDOWS:/cygdrive/c/WINDOWS/System32/Wbem:/cygdrive/c/WINDOWS/System32/WindowsPowerShell/v1.0:/cygdrive/c/WINDOWS/System32/OpenSSH:/cygdrive/c/Users/Bruker/AppData/Local/Microsoft/WindowsApps:/cygdrive/c/rakudo/bin:/cygdrive/c/rakudo/share/perl6/site/bin
$ cd /cygdrive/c/rakudo/bin
$ ls -l
-rwxrwx---+ 1 SYSTEM SYSTEM 930663 May 11 2017 libgcc_s_seh-1.dll
-rwxrwx---+ 1 SYSTEM SYSTEM 136146 Mar 30 20:55 libmoar.dll.a
-rwxrwx---+ 1 SYSTEM SYSTEM 56978 May 11 2017 libwinpthread-1.dll
-rwxrwx---+ 1 SYSTEM SYSTEM 7021172 Mar 30 20:55 moar.dll
-rwxrwx---+ 1 SYSTEM SYSTEM 64066 Mar 30 20:55 moar.exe
-rwxrwx---+ 1 SYSTEM SYSTEM 126 Mar 30 20:56 nqp.bat
-rwxrwx---+ 1 SYSTEM SYSTEM 126 Mar 30 20:56 nqp-m.bat
-rwxrwx---+ 1 SYSTEM SYSTEM 242 Mar 30 20:56 perl6.bat
-rwxrwx---+ 1 SYSTEM SYSTEM 248 Mar 30 20:56 perl6-debug-m.bat
-rwxrwx---+ 1 SYSTEM SYSTEM 242 Mar 30 20:56 perl6-m.bat
$ cat perl6.bat
# "C:\rakudo\bin\moar" --execname="%~dpf0" --libpath="C:\rakudo\share\nqp\lib" --libpath="C:\rakudo\share\nqp\lib" --libpath="C:\rakudo\share/perl6/lib" --libpath="C:\rakudo\share/perl6/runtime" C:\rakudo\share\perl6\runtime\perl6.moarvm %*
Notice that the paths in the bat file are not cygwin paths. So that might explain why it does not work..
For example:
$ "C:\rakudo\bin\moar"
-bash: C:\rakudo\bin\moar: command not found
$ /cygdrive/c/rakudo/bin/moar
ERROR: Missing input file.
USAGE: moar [--crash] [--libpath=...] input.moarvm [program args]
moar --dump input.moarvm
moar --help
[...]
Update:
I also tried install Git Bash, and then from the MINGW64 terminal window:
$ echo $PATH
/c/Users/Bruker/bin:/mingw64/bin:/usr/local/bin:/usr/bin:/bin:/mingw64/bin:/usr/bin:/c/Users/Bruker/bin:/c/WINDOWS/system32:/c/WINDOWS:/c/WINDOWS/System32/Wbem:/c/WINDOWS/System32/WindowsPowerShell/v1.0:/c/WINDOWS/System32/OpenSSH:/c/Users/Bruker/AppData/Local/Microsoft/WindowsApps:/usr/bin/vendor_perl:/usr/bin/core_perl
$ PATH=/c/rakudo/bin:$PATH
$ perl6
bash: perl6: command not found
$ moar
ERROR: Missing input file.
USAGE: moar [--crash] [--libpath=...] input.moarvm [program args]
moar --dump input.moarvm
moar --help
[...]
Note that moar is an .exe file while perl6 is a .bat file.
Also it seems perl6 is not "offical" for Cygwin yet according to this issue.

Related

Run scp in a bash script to copy multiple directory from remote

I would like to write a bash script for transferring multiple directories from a Raspberry Pi to my laptop using scp command. But my code only work on one laptop (MacBook Pro 2016), but it failed on another laptop (MacBook Pro 2020), which is quite strange.
What I would like to execute is some command like:
scp -rp pi#192.168.0.163:/home/pi/Documents/data/{directory1,directory2,directory3} .
This command work well when I directly execute it in terminal, on both of the laptop. But when I put it into a bash script:
#!/bin/bash
scp -rp "pi#192.168.0.163:/home/pi/Documents/data/{directory1,directory2,directory3}" "."
it shows error scp: /home/pi/Documents/data/{directory1,directory2,directory3}: No such file or directory on my MacBook Pro 2020, but it works well on my MacBook Pro 2016.
I have checked the bash version on both laptop, but it seems like they don't have too much difference
MacBook Pro 2016: GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin21)
MacBook Pro 2020: GNU bash, version 3.2.57(1)-release (x86_64-apple-darwin22)
Can anyone help me?
-------------------------------- Below are updates --------------------------------
Seem like I didn't explain my problem very well.
My actual situation is a litter more complicated. I am working on a bash script which takes multiple directory as parameter for doing scp from my Raspberry Pi remote. My script.sh is like:
#!/bin/bash
while getopts "hu:" option; do
case $option in
h) # display Help
Help
exit;;
u)
user_list+=("$OPTARG");;
\?) # incorrect option
echo "Error: Invalid option"
exit;;
esac
done
RASPBERRYPI_DATA_PATH="/home/pi/Documents/data"
RASPBERRYPI_ADDR=$1
RASPBERRYPI_USER_NAME="pi"
scp -rp ${RASPBERRYPI_USER_NAME}#${RASPBERRYPI_ADDR}:${RASPBERRYPI_DATA_PATH}/{${user_list[#]// /,}} .
I execute the script in this way:
./script.sh -u "directory1 directory2" 192.168.0.163
It shows error: scp: /home/pi/Documents/data/{directory1,directory2}: No such file or directory on my MacBook Pro 2020, but it works well on my MacBook Pro 2016.
I am a novice in bash development. I think I am having some mistake on grammar. But the script works well on my old MacBook Pro, which is quite strange.
Thank you very much for helping me.
This is due to the double quotes in your script. Remove them and it should work again.
Test with something like this:
cd /tmp
mkdir -p data/{directory1,directory2,directory3}
mkdir -p "data/{directory1,directory2,directory3}"
ls -alrt /tmp/data
output:
drwxr-xr-x 2 tscanlan wheel 64 Nov 12 08:54 directory1
drwxr-xr-x 2 tscanlan wheel 64 Nov 12 08:54 directory2
drwxr-xr-x 2 tscanlan wheel 64 Nov 12 08:54 directory3
drwxr-xr-x 2 tscanlan wheel 64 Nov 12 08:54 {directory1,directory2,directory3}
Why? Brace expansion in bash and zsh just work that way.
https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html
https://zsh.sourceforge.io/Doc/Release/Expansion.html#Brace-Expansion
A correctly-formed brace expansion must contain unquoted opening and closing braces, and at least one unquoted comma or a valid sequence expression. Any incorrectly formed brace expansion is left unchanged.
I would use rsync for this. Rsync is especially useful as it does incremental backup saving you lots of time and bandwidth. You can construct the input directory list from user input and invoke rsync as under
rsync -a /path/to/dir1 /path/to/dir2 user#remoteserver:/path/to/target
What this will do is create the following directories on the target
/path/to/target/dir1
/path/to/target/dir2

Does git create new files during merge or overwrite existing ones

I have a script test.sh
#!/bin/bash
echo start old file
sleep 20
echo end old file
in the repository which I do execute, and in the mean time I git merge other-branch changes like
#!/bin/bash
echo start new file
sleep 20
echo end new file
into the current branch.
It seems that git on Unix (?) does not directly overwrite the existing file node (?) and does instead rm test.sh and creates the new file.
In that way its guaranteed that the script execution will always read the initial file test.sh and terminate with echo end old file.
Note: On my system (Ubuntu 20.04), while executing the script and directy overtwriting the content in an editor, results in executing the new code, which is bad...
Is that correct and is it also correct on Windows with git-for-windows?
I can't answer regarding Windows, but on Ubuntu 18.04 I can confirm that a git checkout or git merge will delete and recreate a changed file, rather than editing it in place. This can be seen in strace output, for example:
unlink("test.sh") = 0
followed later by
openat(AT_FDCWD, "test.sh", O_WRONLY|O_CREAT|O_EXCL, 0666) = 4
It can also be seen if you create a hard link to the file before the git command and then look again afterwards, you will see that you have two different inodes, with different contents. This is to be expected following deletion and recreation, whereas an in-place edit would have preserved the hard linking.
$ ls -l test.sh
-rw-r--r-- 1 myuser mygroup 59 Jun 5 17:04 test.sh
$ ln test.sh test.sh.bak
$ ls -li test.sh*
262203 -rw-r--r-- 2 myuser mygroup 59 Jun 5 17:04 test.sh
262203 -rw-r--r-- 2 myuser mygroup 59 Jun 5 17:04 test.sh.bak
$ git merge mybranch
Updating 009b964..d57f33a
Fast-forward
test.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
$ ls -li test.sh*
262219 -rw-r--r-- 1 myuser mygroup 70 Jun 5 17:05 test.sh
262203 -rw-r--r-- 1 myuser mygroup 59 Jun 5 17:04 test.sh.bak
You mentioned in a comment attached to the question that it is related to Overwrite executing bash script files. Although it would seem not to be the best idea to run a git command affecting a script which is currently still being executed, in fact the delete and recreate behaviour should mean that the existing execution will be unaffected. Even if the bash interpreter has not yet read the whole file into memory, it will have an open filehandle on the existing inode and can continue to access its contents even though that inode is no longer accessible via the filename that it had. See for example What happens to an open file handle on Linux if the pointed file gets moved or deleted
On Windows with git-for-windows I see the same behavior:
$ mklink /H test.sh.bak
$ fsutil hardlink list test.sh.bak
test.sh.bak
test.sh
$ git merge test
$ fsutil hardlink list test.sh.bak
test.sh.bak
Meaning the hard link did not get preserved, meanin a new file has been created.

Accessing existing Windows environment variables from WSL

I would like to access existing Windows environment variables such as USERPROFILE from withing the WSL bash prompt. There is information from Microsoft on the use of WSLENV here, and I have tried to work with this:
I added WSLENV as a new System variable within the usual Windows "Environment Variables" control panel, setting it to USERPROFILE/u. I then open Ubuntu from the taskbar, and type:
$ echo $USERPROFILE
...but nothing is returned.
Improved Gábor's answer, since as I've discovered it had a small bug, variables obtained that way contain invisible carriage return character, that could cause unexpected issues latter.
Here is Example:
$ cd /mnt/c/
$ mkdir Windows_NT
$ tmpvar=`/mnt/c/Windows/System32/cmd.exe /C "echo %OS%"`
$ echo $tmpvar
Windows_NT
All seems to be ok, but no:
$ cd $tmpvar
: No such file or directory
This is because tmpvar variable contains additional carriage return character (aka ^M or \r) at the end. We can check this via ls command:
$ ls -ld $tmpvar
ls: cannot access 'Windows_NT'$'\r': No such file or directory
In order to remove that character, output could be be additionally processed with sed or tr:
tmpvar=$(cmd.exe /C echo %OS%|sed $'s/\r$//')
or
tmpvar=$(cmd.exe /C echo %OS%|tr -d '\r')
I've also simplified command a bit. Path /mnt/c/Windows/System32 is already included in $PATH WSL variable by default in recent Windows 10 updates, so just cmd.exe should work.
Now, ls and cd commands work without errors:
$ ls -ld $tmpvar
drwxrwxrwx 1 ubuntu ubuntu 512 Feb 12 05:38 Windows_NT
$ cd $tmpvar
$ pwd
/mnt/c/Windows_NT
pwd command confirms that current directory is correct.
Got a workaround for ya.
$ /mnt/c/Windows/System32/cmd.exe /C "echo %OS%"
Windows_NT
$ tmpvar=`/mnt/c/Windows/System32/cmd.exe /C "echo %OS%"`
$ echo $tmpvar
Windows_NT
I haven't checked WSLENV but the upper one should work. Far from being elegant though.
As this question is from early 2018, my first thought is that the Windows 10 build #user2023370 used was not yet 17063.
Other things to point out:
When setting environment variables from the control panel, make sure that the WSL process is not already running.
Because the USERPROFILE environment variable is a path, you need to add the /p option:
WSLENV=USERPROFILE/up
To test how /p option affects the passed variable, try this in cmd.exe:
Microsoft Windows [Version 10.0.19044.1706]
(c) Microsoft Corporation. All rights reserved.
C:\Users\arttu>set WSLENV=USERPROFILE/up
C:\Users\arttu>wsl
$ echo $USERPROFILE
/mnt/c/Users/arttu
$ exit
logout
C:\Users\arttu>set WSLENV=USERPROFILE/u
C:\Users\arttu>wsl
$ echo $USERPROFILE
C:\Users\arttu

Tomatousb, ls command is broken and returns just the query

I made ipkg upgrade on my old tomatousb, which it seems resulted at least in a broken ls command:
[root#tomatousb root]$ /bin/ls /
/
[root#tomatousb root]$ ls /bin
/bin
however, the results are displayed in different colours.
There is also strange behaviour:
[root#tomatousb root]$ echo $PATH
echo $PATH
sh: echo: Permission denied
[root#tomatousb root]$ /bin/echo $PATH
/bin/echo $PATH
/opt/bin:/opt/sbin:/bin:/sbin:/usr/bin:/usr/sbin
I have no glue what's wrong to it.
The logs I see are as following:
/var/log/messages
Jan 1 04:00:11 tomatousb user.info kernel: ipt_recent v0.3.1: Stephen Frost <sfrost#snowman.net>. http://snowman.net/projects/ipt_recent/
Jan 31 23:10:21 tomatousb user.notice root: <<<< MPCSD: Config-files not found in /jffs/config/mpcs & /opt/etc/mpcs!!! Exit. >>>>
Jan 31 23:11:02 tomatousb cron.err crond[143]: time disparity of 25290430 minutes detected
Jan 31 23:37:26 tomatousb authpriv.info dropbear[505]: Child connection from *.*.*.*:*
So, basically, when I do SSH, I get to dropbear.
It seems that during the last ipkg upgrade I got new bash, tcpdump, and two more items, but I can't recall which exactly.. And I can't find the ipkg logfile...
Finally I bumped into my own old discussion when I had the same issue with the same box, and here's what was the reason:
[root#tomatousb mnt]$ cat /opt/etc/profile
#
# Bash initialization script
#
PS1="[\u#\h \W]$ "
PATH=/opt/sbin:/opt/bin:/sbin:/bin:/usr/sbin:/usr/bin
LD_LIBRARY_PATH=/opt/lib:${LD_LIBRARY_PATH}
export PS1 PATH LD_LIBRARY_PATH
[root#tomatousb mnt]$ rm /opt/etc/profile
Then I did reboot, and everything restored back to normal operation!
Do not know what exactly was in that profile file that ruined everything and caused 'memory exhausted' error when running vi.

JSON2CSV install/setup issue (via Go)

I'm attempting to install https://github.com/jehiah/json2csv. The problem is apparently tied to my noob status w.r.t. Bash.
System: Ubuntu 14.04 LTS
Load instruction:
$ go get github.com/jehiah/json2csv
Go is installed:
$ which go ==> /usr/bin/go
~/.bashrc setup:
export GOROOT=/usr/bin/go
export GOPATH=$HOME/projects/go
The package seems to download correctly:
$ cd projects/go
$ tree
$ > bin > json2csv
> src > github.com
...
$ ls bin -l
$ > -rwxrwxr-x 1 <user> <user> 55400 Feb 5 13:57 json2csv
But $json2csv isn't recognized, even from the same directory. I'm sure this is a noob problem, but I haven't cracked it yet. Suggestions?
Add $GOPATH/bin to your PATH variable in your shell,
for bash:
export PATH=$GOPATH/bin:$PATH

Resources