Bash script which works on both Windows and Mac - windows

Wirting a simple bash script
#!/bin/bash
wget -q https://get.helm.sh/helm-v${HELM_VERSION}-linux-amd64.tar.gz
tar -zxf helm-v${HELM_VERSION}-linux-amd64.tar.gz
mv ./linux-amd64/helm ${BIN_PATH}/helm
rm -rf linux-amd64/ helm-v${HELM_VERSION}-linux-amd64.tar.gz
chmod +x ${BIN_PATH}/helm
But I have to remove the end-of-line (CRLF & LF) every time I switch from Windows to Mac or vice-versa.
At the package doc2unix (https://formulae.brew.sh/formula/dos2unix) to handle these at the moment.
Is there any best practice how to handle this, so scripts can work seamlessly without any changes?

There are a few options,
If you are using a Git repository or a version control system, where a setting is available to automatically change line endings, from LF to CRLF. When a user downloads a script. Most users have a version control system, and prefer this method, if it is just line endings you are dealing with, when it comes to running the same script.
Have two versions of a file within two folders, which is one for Windows and one for Linux, or in your script write some code to detect what the OS is and then run your code which would work with the OS.
Software which can convert a file for executing from Windows to Linux, you are using one already called doc2unix

Related

Issue with line endings when developing on a Windows but running on a UNIX docker container

My team are building our first docker based .NET app and have written a bash script that runs as part of the build process (from the dockerfile). We are all on Windows 10 machines.
When the bash script runs, it throws an error:
/bin/bash^M: bad interpreter: No such file or directory.
From my research, this appears to be because of line endings being Windows line endings, not UNIX based. I was able to fix this by converting the endings using Notepad++ and the script ran fine. However, when I went into SourceTree to see the changed files, it briefly showed as a changed file (with something saying it couldn't detect changes). Once I clicked the stage file button, it disappeared as if there wasn't any changed files.
How do I resolve this? I can see a line endings setting in GIT but not sure what the right setting should be.
Using dos2unix will help you with this problem. What dos2unix does is it removes the hidden windows characters that you encounter (^M).
Windows-based text editors put special characters at the end of lines
to denote a line return or newline. Normally harmless, some
applications on a Linux server cannot understand these characters and
can cause the service to not respond correctly.
If you don't have dos2unix in your linux machine yet:
Install dos2unix
apt install dos2unix
Run dos2unix on your problematic file
dos2unix your_problematic_file.txt
You are probably looking for the .gitattributes file.
It allows you to set in which files you want which line endings.
Read more here: Documentation
Add a .gitattributes file to the top of your repository with the following contents.
* text=auto
*.sh text eol=lf
*.conf text eol=lf
Source

Copied a bunch of files from windows to ubuntu server and now all the files are showing modified in git with ^M

Transferred over 50k files from my windows box to my ubuntu server and now git diff is showing all my files are modified with ^M at the line endings.
I tried changing the auto.crlf to true in the command line and it doesn't work.
And no I can't recopy this over again as I don't have access to the windows box anymore.
I've constantly run into this and I never found a simple way to fix this.
Isn't there a simple option in the command line git to just ignore these ^M line endings? I don't want to go through to having to make a script and reprocess all 50k files just to remove the ^M line endings.
auto crlf defines what happens during checkin and checkout.
If the files are already changed, then you may need to use a script after all. If you have the dos2unix utility available you could just run that and specify all the files.
In the meantime, make sure you have the auto crlf conversion setup the way you want it so this doesn't come up again.

Shell (Bash) - Can I have fully portable .bash_profile / .bashrc / .bash_history files?

Background
I'm a Front End Web Developer that has started moving to PortableApps where I can; at least for the desktop machines I use (Windows) after building a machine and having to re-install Windows multiple times.
It's getting more and more important to use the command line with build automation tools, testing software with a CLI etc.
I have just got portable versions of Git (Bash) and ConEmu working from my Dropbox (but ideally this would work from USB too). This means I have access to a Unix shell on Windows with Git, but the .bash_profile (and .bashrc) I have saved I need to manually copy to the '~' (home) directory for each machine I use.
Question
Is there a way to link my portable console with bash files not located in the home directory of the user on each machine used?
For instance when my console opens and looks for these files, can I ask it to check a different directory without setting any config on each machine? And then get the .bash_history to save here too instead?
You can use symbolic links for .bash_profile and .bashrc:
ln -s /path/to/.bashrc ~/.bashrc
ln -s /path/to/.bash_profile ~/.bash_profile
And inside your .bashrc you can define where your history file is located:
export HISTFILE=/path/to/.bash_history
I don't think there's any way around having .bashrc and .bash_profile in your home directory. Unless you start bash with the --rcfile option:
bash --rcfile /path/to/.bashrc
There is also the system wide file located at /etc/bashrc.

Git print files in Windows Format

The most common use case I deal with git is to checkout file or remove or add file from Windows Command prompt.
I don't intend to use fancy gui tools. I like to work with keyboard and command prompt as much as possible.
So whenever I ask git status or any other report, git prints the file name like this
error: The following untracked working tree files would be overwritten by merge:
Tasks/Test/MyTest.js
The problem is, I can't just copy paste that text and use git checkout or git add anything. Since Windows can't understand / it expects you to give with \
Is there anyway git can print the info in Windows format or Windows can accept the *nix format [del Tasks/Test/MyTest.js]
I just tested Git using the Command Prompt and I had no trouble running git add on a file path which included forward slashes, so I don't see your problem as being reproducible.
Another option for you to consider is to use the Git Bash command line tool which ships with the Windows download of Git. The bash is a window, similar in appearance to the Command Prompt, but more powerful. On my Windows setup the Git Bash program is located here:
C:\Program Files\Git\git-bash.exe
The Git Bash tool does not make a distinction between / and \ in the path. Since either will work, you only need to copy the output you want, which is also easy and straightforward.
And good for you for sticking to command line Git. I believe you will become a stronger Git user by learning the nuts and bolts first on the command line.

How do I run .sh or .bat files from Terminal?

I have a pretty basic problem here, that has happened so haphazardly to me that up until now, I've just ignored it. I downloaded tomcat web server and "Murach's Java Servlets and JSP" book is telling me to navigate to the tomcat/bin directory and start the server my typing in Terminal
$ startup
However, I get the error
-bash: startup: command not found
The relevant files in this directory are startup.sh and startup.bat. Typing both of these returns the same error message
So my questions are, what are .bat and sh files, and how do I run these files? I've read several tutorials for different languages and software programs, and some times when the tutorial says execute a bunch of files in the command line, I get a "command not found" error. Sometimes it works, sometimes it doesn't. This is perplexing to me, so what are some common solutions to solving these sort of "command not found" Terminal problems?
The .sh is for *nix systems and .bat should be for Windows. Since your example shows a bash error and you mention Terminal, I'm assuming it's OS X you're using.
In this case you should go to the folder and type:
./startup.sh
./ just means that you should call the script located in the current directory. (Alternatively, just type the full path of the startup.sh). If it doesn't work then, check if startup.sh has execute permissions.
This is because the script is not in your $PATH. Use
./scriptname
You can also copy this to one of the folders in your $PATH or alter the $PATH variable so you can always use just the script name. Take care, however, there is a reason why your current folder is not in $PATH. It might be a security risk.
If you still have problems executing the script, you might want to check its permissions - you must have execute permissions to execute it, obviously. Use
chmod u+x scriptname
A .sh file is a Unix shell script. A .bat file is a Windows batch file.
Type bash script_name.sh or ./script_name in linux terminal. Before using ./script_name make you script executeable by sudo chmod 700 script_name and type script_name.bat in windows.
Drag-And-Drop
Easiest way for a lazy Mac user like me: Drag-and-drop the startup.sh file from the Finder to the Terminal window and press Return.
To shutdown Tomcat, do the same with shutdown.sh.
You can delete all the .bat files as they are only for a Windows PC, of no use on a Mac to other Unix computer. I delete them as it makes it easier to read that folder's listing.
File Permissions
I find that a fresh Tomcat download will not run on my Mac because of file permission restrictions throwing errors during startup. I use the BatChmod app which wraps a GUI around the equivelant Unix commands to reset file permissions.
Port-Forwarding
Unix systems protect access to ports numbered under 1024. So if you want to use port 80 with Tomcat you will need to learn how to do "port-forwarding" to forward incoming requests to port 8080 where Tomcat listens by default. To do port-forwarding, you issue commands to the packet-filtering (firewall) app built into Mac OS X (and BSD). In the old days we used ipfw. In Mac OS X 10.7 (Lion) and later Apple is moving to a newer tool, pf.
Based on IsmailS' comment the command which worked for me on OSX was:
sudo sh ./startup.sh
On windows type either startup or startup.bat
On unix type ./startup.sh
(assuming you are located in tomcat/bin directory)
Batch files can be run on Linux. This article explains how (http://www.linux.org/threads/running-windows-batch-files-on-linux.7610/).
Type in
chmod 755 scriptname.sh
In other words, give yourself permission to run the file. I'm guessing you only have r/w permission on it.
add #!bin/bash on top of the your .sh file
sudo chmod +x your .sh file
./your.sh file
these steps work~
My suggestion does not come from Terminal; however, this is a much easier way.
For .bat files, you can run them through Wine. Use this video to help you install it: https://www.youtube.com/watch?v=DkS8i_blVCA. This video will explain how to install, setup and use Wine. It is as simple as opening the .bat file in Wine itself, and it will run just as it would on Windows.
Through this, you can also run .exe files, as well .sh files.
This is much simpler than trying to work out all kinds of terminal code.
I had this problem for *.sh files in Yosemite and couldn't figure out what the correct path is for a folder on my Desktop...after some gnashing of teeth, dragged the file itself into the Terminal window; hey presto!!

Resources