- linux include all directories
- 3 Answers 3
- Include Files in a Bash Shell Script With source Command
- 1. Overview
- 2. The source Command
- 2.1. Bash Variables and Definitions of Functions
- 2.2. Other Significant Properties
- 3. Passing Environment Variables From a File
- 4. Building a Library of Functions
- 5. Setting a Correct Path
- 5.1. Providing an Absolute Path
- 5.2. Using the dirname Command
- 5.3. Make Use of the PATH Environment Variable
- 6. Passing Arguments With the source Command
- 7. Availability and Compatibility
- 8. Conclusion
- How To Include Files From Multiple Directories In C on Linux?
- 1 Answer 1
linux include all directories
how would I type a file path in ubuntu terminal to include all files in all sub-directories? If I had a main directory called «books» but had a ton of subdirectories with all sorts of different names containing files, how would I type a path to include all files in all subdirectories? /books/.
in what context? in a scripting language or at the command line as input to a shell command? some more info would be useful..
Typically, if a tool supports this, there will be a flag that can be passed to the tool to recurse subdirectories.
3 Answers 3
From within the books top directory, you can use the command:
Then, if you wanted to, say run each file through cat, you could use the xargs command:
For more info, use commands:
This is the correct way to traverse a hierarchy of subdirectories. Some shells offer a wildcard syntax **/* for this but Bash v2 is not amongst them.
Any Ubuntu version that is yet supported uses bash version 3 or higher for the terminal (as far as I know).
It is unclear what you actually want . Probably you will get a better solution to your problem, if you ask directly for it, not for one other problem you’ve come accross trying to circumvent the original problem.
do you mean something like the following?
where the first * expands for all subdirectories and the second * for all contained files ?
I have chosen the file command arbitrarily. You can choose whatever command you want to run on the files you get shell-expanded. Also note that directories will also be included (if not excluded by name, e.g. *.png or *.txt ). The wildcard * is not exactly the file path to include all files in all subdirectories but it expands to all files (or directories) matching the wildcard expression as a list, e.g. file1 file2 file3 file4 . See also this tutorial on shell expansion.
Note that there may be easy solutions to related problems. Like to copy all files in all subdirectories ( cp -a for example, see man cp ).
I also like find very much. It’s quite easy to generate more flexible search patterns in combination with grep . To provide a random example:
du `find . | grep some_pattern_to_occur | grep -v some_pattern_to_not_occur`
Include Files in a Bash Shell Script With source Command
The Kubernetes ecosystem is huge and quite complex, so it’s easy to forget about costs when trying out all of the exciting tools.
To avoid overspending on your Kubernetes cluster, definitely have a look at the free K8s cost monitoring tool from the automation platform CAST AI. You can view your costs in real time, allocate them, calculate burn rates for projects, spot anomalies or spikes, and get insightful reports you can share with your team.
Connect your cluster and start monitoring your K8s costs right away:
1. Overview
In this tutorial, we’re going to learn how to include a file in a bash script. This is a way to import environment variables, reuse existing code, or execute one script from within another.
Two illustrative examples concern importing environment variables and building a library of functions.
2. The source Command
The built-in bash source command reads and executes the content of a file. If the sourced file is a bash script, the overall effect comes down to running it. We may use this command either in a terminal or inside a bash script.
To obtain documentation concerning this command, we should type help source in the terminal. We assume that Bash (Bourne again shell) is not in POSIX mode is through the whole tutorial.
2.1. Bash Variables and Definitions of Functions
When we execute the script using the source command, it is run in the same shell where we source it. Consequently, the script accesses all variables from the shell where the source command is issued. This communication works in the opposite direction – all definitions from the sourced file become available in the parent shell.
On the other hand, when we run a script with the bash command or just by typing its name, a new shell instance is created. Therefore, the script can access only variables and functions defined with keyword export in the parent shell. In addition, all definitions of the descendant shell disappear when it exits.
As a simple example, let’s write script test_var:
#!/bin/bash echo "expVar = $expVar" echo "myVar = $myVar"
Let’s set the variables in the terminal then run the script in both ways to compare results:
export expVar = "Exported variable" myVar="My variable" ./test_var expVar = Exported variable myVar = source test_var expVar = Exported variable myVar = My variable
This characteristic makes the source command extremely useful to share content and functionality between different files.
2.2. Other Significant Properties
In addition, the source command’s features include:
- it searches for the script in folders listed in the PATH variable of the current shell
- it recognizes an absolute or relative path given to the script
- the script does not need to be executable
- it returns the status of the last executed command in the script
- if sourced script issues the exit command, the sourcing one exits, too
3. Passing Environment Variables From a File
In this example, we’re going to import a set of environment variables into a script. The well-known case is reading and setting variables from the user’s .bash_profile (or .profile).
This is especially useful in the case of cron jobs because the shell of cron usually has a very sparse set of environment variables.
Let’s assume that we want to pass all environment variables of the user’s interactive shell to the cron job script. So, let’s begin the script by sourcing profile files:
#!/bin/bash source /etc/profile source ~/.bash_profile source ~/.bashrc # do something useful
Of course, we don’t need to limit ourselves to reusing the user’s profiles. We can collect any useful and meaningful variables in the file and import them into the script.
4. Building a Library of Functions
Let’s create a library of reusable functions, define them in a separate file, and use them in another script afterward.
As an example, suppose our lib_example library contains two functions:
- my_name to find the name of the current user (with the whoamicommand)
- my_used_disk_space to calculate the disk space occupied by the user’s home directory (uses the du command). In addition, cut removes the folder name from the output of du.
Let’s define the functions:
#!/bin/bash function my_name() < whoami >function my_used_disk_space()
With the help of the source command, we can access these functions from another script, lib_test:
#!/bin/bash source lib_example echo "My name is $(my_name), I am using $(my_used_disk_space)"
Let’s start the script and check the result:
./lib_test My name is joe, I am using 46G
5. Setting a Correct Path
Let’s take a closer look at the structure of the exemplary library from the previous section.
Both scripts, the sourced lib_example and the sourcing lib_test, are located in the same directory. However, command source lib_example tries to find the script in the directory where lib_test is invoked.
As a result, this solution is very error-prone. In fact, it works correctly only if we start the lib_test from the folder where it’s located. After calling the script from another directory, we obtain a bunch of errors.
Let’s examine the ways to improve the structure of our library.
5.1. Providing an Absolute Path
We can precede the name of the sourced script with its full path:
source /home/joe/example/lib_example
It’s a rock-solid solution, although it demands rewriting the script when we change its location.
5.2. Using the dirname Command
Let’s try to avoid the hardcoding of paths. We know that both scripts are in the same folder. Furthermore, we use dirname to extract the path from the name of the wrapper script.
We should change the argument of the source command in the lib_test script to:
source $(dirname "$0")/lib_example
The dirname argument $0 is just the full name of the sourcing script.
5.3. Make Use of the PATH Environment Variable
In addition, since source searches for files in folders listed in PATH, we should reorganize our library.
Let’s examine the PATH of our exemplary user joe:
/home/joe/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/joe/.local/bin:/home/joe/.local/bin
Now, we’re going to copy lib_example to the /home/joe/.local/bin folder.
Hence, the sourcing is now in the same form as at the very beginning – source lib_example – but the sourced script may be found on PATH, and the script lib_test works correctly.
6. Passing Arguments With the source Command
Bash scripts accept arguments. Accordingly, the source command allows passing arguments to the script. However, in the case of sourcing from another script, the logic behind is a little more complicated than the use in the terminal.
Let’s start with the simplest example, a script arg_list that outputs all of its bash arguments:
Let’s check how it works inside another script, arg_test:
#!/bin/bash source arg_list foo_bar
Afterward, we start the new script with two arguments:
./arg_test foo bar My argument(s): foo_bar
We should notice that source passes the argument foo_bar to the included script independently of the arguments foo and bar of the wrapping script.
Let’s change arg_test a bit to show an essential feature of the source command. We’re going to skip the argument of the arg_list script:
One more time, let’s examine the result:
./arg_test foo bar My argument(s): foo bar
So, it’s different from the expected empty string.
In fact, inside another script, source passes the arguments of the wrapping script to the sourced one, unless the latter’s arguments are explicitly given.
This is an important point that we should be aware of – mainly if the operation of the included script relies on the number of its arguments.
7. Availability and Compatibility
The usefulness of the source command is somehow reduced by its prevalence. Hence, we should be aware of different implementations of the bash shell language.
As a matter of fact, only Bourne again shell (Bash) provides this command in this form. Debian Almquist Shell (Dash) or Bourne Shell (sh), to name only a few, offer the . command (‘dot’) instead. Of course, ‘dot’ is present in Bash, too.
The purpose of the ‘dot’ command is the same as that of source, but its functionality is slightly different.
On the other hand, its advantage is the POSIX compliance. As a result, scripts that use ‘dot’ are portable and run with any POSIX compliant bash language implementation.
Moreover, Bash can also work in the POSIX mode, subsequently changing the behavior of source. Without going into details, the presented description of the command concerns Bash in a non-POSIX mode.
8. Conclusion
In this article, we learned about the source command. We applied it to include files into a bash script. Subsequently, we studied cases of importing shell variables and setting up a library of functions.
How To Include Files From Multiple Directories In C on Linux?
Now I am trying to run main.c which contains #include directive to include header files from include directory and function calls to .c files in both common and src directories. I am using -I option but it is useful only for one directory path indication. How does the compiler will look in all src, common and include directories to resolve the calls. Kindly suggest me a command or make file to provide path of multiple directories while compiling with gcc.
1 Answer 1
Multiple -I options are permitted. The description of the -I option from Options for Directory Search states:
Add the directory dir to the head of the list of directories to be searched for header files. This can be used to override a system header file, substituting your own version, since these directories are searched before the system header file directories. However, you should not use this option to add directories that contain vendor-supplied system header files (use -isystem for that). If you use more than one -I option, the directories are scanned in left-to-right order; the standard system directories come after.
gcc main.c -o main -Iinclude -Isrc/include -Icommon/include
Note that if main.c is using functions implemented in another .c file(s) then the other .c files will also need compiled and linked into the final program binary. For example:
gcc main.c src/another.c -o main -Iinclude -Isrc/include -Icommon/include