16

This is a case of the documentation being stricter than the implementation, possibly in an attempt to lower the footgun factor. This has been discussed here before; see also the exhaustive test establishing that for example [}{ is a valid function name. It may also be worth noting that abc::def is not a valid variable name: $ abc::def=foo bash: abc::def=...


10

You also have an alias in functons.shwith the same name as a function in your other file. In functons.sh: alias zzz=sz In z.sh: zzz () { df -h } This confuses bash. Example: $ cat f1 foo () { echo hello; } alias xfoo=foo $ cat f2 xfoo () { echo beep; } $ source f1 $ source f2 $ shopt -s extdebug $ declare -F foo foo 1 f2 Without the xfoo alias ...


10

If you try cd () { echo "Improved CD !" # Improvement one; cd # Improvement two; # Do cool stuff... } cd without command, cd will call the cd function, which will call the cd function, which will call the cd function, and so on: the cd statement inside the function calls the cd function, not the cd built-in. You’ll see “Improved CD !” ...


9

return does an explicit return from a shell function or "dot script" (a sourced script). If return is not executed, an implicit return is made at the end of the shell function or dot script. If return is executed without a parameter, it is equivalent of returning the exit status of the most recently executed command. That is how return works in all POSIX ...


8

What you should really do is source the file containing the functions inside the script itself, that way it won’t be context-dependent (or rather, it will be less context-dependent).


7

From the bash(1) man page: When executed, the exit status of a function is the exit status of the last command executed in the body.


6

If you use set -a either in your .bashrc or within the function file itself it will mark all functions to be exported. 4.3.1 The Set Builtin -a Each variable or function that is created or modified is given the export attribute and marked for export to the environment of subsequent commands. This may cause some undesirable results if you are ...


6

You could try something like: declare -fx $(bash -c 'source /path/to/my-file &> /dev/null; compgen -A function') Since you want to export only functions from the file, sourcing it in a new instance of bash and then using compgen -A function will list names of all the functions defined in that file (and previously exported functions too, but that ...


6

To append new elements to an array: array+=( new elements here ) In your case: my_array+=( "$extracted_value" ) When you do array+=$variable you are appending to the first element of the array. It is the same as array[0]+=$variable Also note that in extracted_value=$( ./external_script.sh $file $sub_unit ) the values $file and $sub_unit will be ...


5

The shell is just really picky about the syntax and whitespace with the { ... } construct. These two ways to set up that function would work: ok() { grep ERROR $filename; } ok() { grep ERROR $filename } Regarding braces { .. } vs. parenthesis ( .. ), Bash's manual states that: The semicolon (or newline) following list is required. and The braces ...


5

alias 'gsi=<<eof grep --color' Would work as alias is just like preprocessor text replacement, where the replacement is interpreted as shell code again. Yours was not working as you had that "$1". With gsi file.txt replaced with cat <<eof | grep --color "$1" file.txt, then the shell carries on interpreting that command line and $1 at that point ...


4

You have demonstrated multiple anti-patterns in your code which could be improved. See Why you shouldn't parse the output of ls(1). You don't need to parse the output of ls command and avoid using multiple shell pipe-lines with tr command and find. It is recommended better to use the glob options provided by the native shell which in your case should be the ...


4

They are showing the same result because you are only passing one positional parameter per function call. In order for mars to be the second parameter you would need to call like this: lets_print Earth Mars Recommended reading on positional parameters: 3.4.1 Positional Parameters


4

Note: the statements here apply to Bash version 4.0.35 and up. Implementations of set -e vary wildly among different shells/versions. Follow Stéphane's advice and don't use set -e. man bash in the Shell Builtin Commands/set section explains things pretty well though the text is a little dense and requires a bit of focus. To your specific questions the ...


4

Your function would not be using a here-document: gsi () { grep --color "$@" } This would enable you to pass a pattern as well as any other options to grep on the common line and grep would read from standard input. The end of the input would be signalled by pressing Ctrl+D. The above would possibly intermingle the pasted contents and the result from ...


4

Its role is exactly analogous to that in the case of variables - i.e. to export the definition to inherited environments. So $ foo() { echo bar; } $ foo bar Start a child shell $ bash Now: $ foo Command 'foo' not found, did you mean: command 'roo' from snap roo (2.0.3) command 'fio' from deb fio command 'fgo' from deb fgo command 'fog' from ...


4

The ssh command captures local stdin and can also run external commands. If you combine these two facts then this becomes possible: ssh machine2 tee -a "~/.ssh/authorized_keys" < ~/.ssh/id_dsa.pub There is also a command called ssh-copy-id intended to automate this process. You can see man ssh-copy-id for more information.


4

Quote the variable expansions. If we have a script foo.sh: $ cat foo.sh #!/bin/sh args() { printf ">%s<\n" "$@" } args "$1" "" foo And we call it with sh foo.sh "", the output is: >< >< >foo< That is, one empty argument from "$1" (the argument to foo.sh), another from the hard-coded "" in the script, and then the fixed ...


4

Your commands don't work the way you expect them to because the test does not output anything to its standard output stream. It's the standard output stream that gets piped to the next command in a pipeline (your first command), and it's the standard output that replaces a command substitution (your second command). As an aside, note that even if the left ...


3

The function is found and executed but it contains command waldo That's what the error message refers to. You could handle this problem in the function: if hash waldo >/dev/null 2>&1; then command waldo "$@" else echo 'ERROR: ...' fi


3

You will have to make sure that the function is available to the script. You can do this in two ways: source the file that contains the function definition, or export the function before calling the script (export -f rse would export the function). Functions, just like shell variables, are not part of the environment that gets inherited by scripts. Shell ...


3

You defined a function called alias, added a line to .bashrc that calls alias ..., and then sourced .bashrc into your shell (which has the function defined in it already). The alias you sourced calls the function, which adds another line and sources the script again, calling the function again once for each time it's already run, leading to exponential ...


3

Your function creates info.php but then immediately deletes it. After creating the file info.php, it seems like you intend for the next command to schedule its deletion: rm "$drt"/info.php | at now + 2 hours But that's not what is happening. That runs the rm command right now, then pipes its standard output (to which nothing would typically be written, as ...


3

Redirect the debugging output to standard error: foo () { echo 'In foo' >&2 VAR="1234" echo 'Calculated item' >&2 echo "$VAR" } RESULT=$(foo) printf 'RESULT="%s"\n' "$RESULT" You could even create a dedicated "debug" function: debug () { printf 'DEBUG: %s\n' "$@" >&2 } foo () { debug 'In foo' VAR="1234" ...


3

Why are you putting shell function parameters inside parentheses? Try this: function alterpdf(){ swap titlepage_$1.tex titlepage_$2.tex swap titlepage_$1.pdf titlepage_$2.pdf pdflatex allTitle page.tex }


3

It's called a compound command and the syntax is { compound-list; } (this is an example of a compound command, other things like for loops etc. are also compound commands) For example: { echo 'hello' echo 'world' } The ; is only needed if there's no newline before the final }: { echo 'hello'; echo 'world'; } The commands in the { ...; } ...


3

Data structures other than strings can't really be passed around between shell functions. However, you may use name references to pass names of associative arrays (or of whatever other variable you may want). Name references are available in bash since release 4.3. Example: foo () { declare -n aarr="$1" aarr["fookey"]=foovalue } declare -A ...


3

The error is here: if ( a == "-u" ); then echo "This means upload" else echo "This means download" fi The if construct expects an expression that can be evaluated to true or false. So, for example, a command (if ls; then echo yes;fi) or a test construct. You want to use a test construct but you're not using the test operator ([), you are using ...


3

You can do something like this: cat ~/.ssh/id_dsa.pub | ssh machine2 'cat >> ~/.ssh/authorized_keys' But you should probably use ssh-copy-id instead, which is a tool for that exact purpose: ssh-copy-id machine2 or ssh-copy-id id_dsa machine2


3

In older bashes, you need "variable indirection" (4th paragraph of Shell Parameter Expansion), which is really ugly for arrays: myArray=('1' '2' '3' '4' '5') myFunction() { local arr="${1}[@]" # array expansion *as a string* local values=( "${!arr}" ) # actual array expansion echo "${values[@]}" } myFunction myArray 1 2 3 4 5 Note ...


Only top voted, non community-wiki answers of a minimum length are eligible