What is the Bash file extension?
I have written a bash script in a text editor, what extension do I save my script as so it can run as a bash script? I’ve created a script that should in theory start an ssh server. I am wondering how to make the script execute once I click on it. I am running OS X 10.9.5.
Its usually .sh , but the extension isn’t required to exist at all. Linux is not Windows. The program that shall interpret your script is determined in its first line, that should be #!/bin/bash . It may even include parameters.
@anubhava How would i get my script to execute if i were just to double click on it and not actually type » bash myscript»
5 Answers 5
Disagreeing with the other answers, there’s a common convention to use a .sh extension for shell scripts — but it’s not a useful convention. It’s better not to use an extension at all. The advantage of being able tell that foo.sh is a shell script because of its name is minimal, and you pay for it with a loss of flexibility.
To make a bash script executable, it needs to have a shebang line at the top:
and use the chmod +x command so that the system recognizes it as an executable file. It then needs to be installed in one of the directories listed in your $PATH . If the script is called foo , you can then execute it from a shell prompt by typing foo . Or if it’s in the current directory (common for temporary scripts), you can type ./foo .
Neither the shell nor the operating system pays any attention to the extension part of the file name. It’s just part of the name. And by not giving it a special extension, you ensure that anyone (either a user or another script) that uses it doesn’t have to care how it was implemented, whether it’s a shell script (sh, bash, csh, or whatever), a Perl, Python, or Awk script, or a binary executable. The system is specifically designed so that either an interpreted script or a binary executable can be invoked without knowing or caring how it’s implemented.
UNIX-like systems started out with a purely textual command-line interface. GUIs like KDE and Gnome were added later. In a GUI desktop system, you can typically run a program (again, whether it’s a script or a binary executable) by, for example, double-clicking on an icon that refers to it. Typically this discards any output the program might print and doesn’t let you pass command-line arguments; it’s much less flexible than running it from a shell prompt. But for some programs (mostly GUI clients) it can be more convenient.
Shell scripting is best learned from the command line, not from a GUI.
(Some tools do pay attention to file extensions. For example, compilers typically use the extension to determine the language the code is written in: .c for C, .cpp for c++, etc. This convention doesn’t apply to executable files.)
Keep in mind that UNIX (and UNIX-like systems) are not Windows. MS Windows generally uses a file’s extension to determine how to open/execute it. Binary executables need to have a .exe extension. If you have a UNIX-like shell installed under Windows, you can configure Windows to recognize a .sh extension as a shell script, and use the shell to open it; Windows doesn’t have the #! convention.
How to check the extension of a filename in a bash script?
I am writing a nightly build script in bash.
Everything is fine and dandy except for one little snag:
#!/bin/bash for file in "$PATH_TO_SOMEWHERE"; do if [ -d $file ] then # do something directory-ish else if [ "$file" == "*.txt" ] # this is the snag then # do something txt-ish fi fi done;
My problem is determining the file extension and then acting accordingly. I know the issue is in the if-statement, testing for a txt file. How can I determine if a file has a .txt suffix?
In addition to the answer of Paul, you can use $(dirname $PATH_TO_SOMEWHERE) and $(basename $PATH_TO_SOMEWHERE) to split into folder and directory and do something directory-ish and file-ish
11 Answers 11
That is, double brackets and no quotes.
The right side of == is a shell pattern. If you need a regular expression, use =~ then.
I didn’t know about this. It seems to be a special case that the right-hand side of == or != is expanded as a shell pattern. Personally I think this is clearer than my answer.
I am new to bash and it took me a little while to figure out how to use this in a multi conditional if statement. I am sharing it here in case it helps someone. if [[ ( $file == *.csv ) || ( $file == *.png ) ]]
@cheflo that’s good for multiple conditions in general. In this specific case, you could also use if [[ $file =~ .*\.(csv|png) ]] . It’s shorter, clearer, easier to add additional extensions and could be easily made configurable (by putting «csv|png» in a variable).
You can put double quotes around the file. if [[ «$file» == *.txt ]] If the file has spaces in its name, double-quoting is required.
@shawnhcorey There is no need for quoting $file, even if it contains a space. The [[ command does not do word splitting (nor pathname expansion). That is one of the main differences between [[ and [, and one of the main reasons to use [[.
I think you want to say «Are the last four characters of $file equal to .txt ?» If so, you can use the following:
Note that the space between file: and -4 is required, as the ‘:-‘ modifier means something different.
In bash, this will produce a «[: ==: unary operator expected» error unless you put quotes around the first variable. So if [ «$
A note for those that may be new to the bash/shell syntax: the space before the -4 is significant. «$
if [ "$" = "txt" ]; then # operation for txt files here fi
You just can’t be sure on a Unix system, that a .txt file truly is a text file. Your best bet is to use «file». Maybe try using:
Then you can use a list of MIME types to match against or parse the first part of the MIME where you get stuff like «text», «application», etc.
You can use the «file» command if you actually want to find out information about the file rather than rely on the extensions.
If you feel comfortable with using the extension you can use grep to see if it matches.
yes I am aware of the file command. I had actually tried matching based on the output of said command. but I fail horribly at these if-statements.
The correct answer on how to take the extension available in a filename in linux is:
Example of printing all file extensions in a directory
for fname in $(find . -maxdepth 1 -type f) # only regular file in the current dir do echo $ #print extensions done
Your answer uses a double backslash, but your example only uses a single backslash. Your example is correct, your answer isn’t.
Can you please explain the answer a little bit or link a documentation? I need to understand what does $
Similar to ‘file’, use the slightly simpler ‘mimetype -b’ which will work no matter the file extension.
if [ $(mimetype -b "$MyFile") == "text/plain" ] then echo "this is a text file" fi
Edit: you may need to install libfile-mimeinfo-perl on your system if mimetype is not available
I wrote a bash script that looks at the type of a file then copies it to a location, I use it to look through the videos I’ve watched online from my firefox cache:
#!/bin/bash # flvcache script CACHE=~/.mozilla/firefox/xxxxxxxx.default/Cache OUTPUTDIR=~/Videos/flvs MINFILESIZE=2M for f in `find $CACHE -size +$MINFILESIZE` do a=$(file $f | cut -f2 -d ' ') o=$(basename $f) if [ "$a" = "Macromedia" ] then cp "$f" "$OUTPUTDIR/$o" fi done nautilus "$OUTPUTDIR"&
It uses similar ideas to those presented here, hope this is helpful to someone.
bash: how do you return file extensions?
I want to write a script to return just the extension of the input file name. For example, textfile.txt should return txt . I’m new to Linux and bash, and I’m trying to learn how to write basic scripts. Thanks!
What is the extension of linux-4.2.3.tar.xz file that you can download from kernel.org? What is the extension of /bin/bash file that is most certainly available at your system? You see, the concept of «file extension» is pretty alien in Linux. The part after the dot carries very little significance for the system — it is rather a cue for the user on what he might expect from that file. And that cue may lie or be wrong.
7 Answers 7
The shell, bash for example, has many string manipulation features. One of them lets you remove everything up to a given pattern:
The syntax above removes everything from the variable $VAR until the first match of the glob GLOB . So, to print a file’s extension without its name, you could do:
Note that this can also deal with more than one «extension»:
$ file="file.new.txt" $ echo $ txt
If you don’t want that, use one # instead, which will remove the shortest match instead of the longest:
Now, to run this on all files in a directory, you could do:
$ ls file.avi file.pdf file.png file.txt $ for file in *; do echo "$file : $"; done file.avi : avi file.pdf : pdf file.png : png file.txt : txt
And, for the sake of completeness, you can also get the file name without its extension using $ :
$ for file in *; do echo "$file : $ : $"; done file.avi : avi : file file.pdf : pdf : file file.png : png : file file.txt : txt : file