Unix & Linux Stack Exchange
Q&A for users of Linux, FreeBSD and other Unix-like operating systems
Latest Questions
3
votes
2
answers
108
views
Localising variables in /bin/sh functions
POSIX defines [shell functions](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_05) as: ``` fname ( ) compound-command [io-redirect ...] ``` The [compound-command](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04) is further d...
POSIX defines [shell functions](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_05) as:
fname ( ) compound-command [io-redirect ...]
The [compound-command](https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_04) is further defined as either:
( compound-list )
{ compound-list ; }
In particular POSIX notes for the first form that "_variable assignments and built-in commands that affect the environment shall not remain in effect after the list finishes._"
I've noticed that the idiomatic structure with bash
code seems to be to use a braced compound list with the local
keyword:
f1() {
local arg1=$1 arg2=$2 p q # arg1, arg2, p, q are all local vars
shift 2
…
}
In general, assuming the function doesn't modify global variables, we can simplify this to use the bracketed form that implicitly localises all its variables:
f2() (
arg1=$1 arg2=$2 # all variables are implicitly local
shift 2
…
)
Aside from using local
as an explicit declaration of local variables, is there any general reason to prefer the braced f1() { …; }
construct, which seems to be more commonly used than f2() ( … )
?
Chris Davies
(126603 rep)
Jul 30, 2025, 04:18 PM
• Last activity: Aug 1, 2025, 01:09 PM
27
votes
5
answers
15776
views
How to get current buffer's filename in emacs?
One of the main features I miss about Vim, is that it always saves the filename of the current file in the `%` buffer ([more info][1]). That allows launching commands easily like: ;; compile current file :! gcc % ;; source current file (useful when I'm editing .vimrc :source % ;; get the size of cur...
One of the main features I miss about Vim, is that it always saves the filename of the current file in the
%
buffer (more info ). That allows launching commands easily like:
;; compile current file
:! gcc %
;; source current file (useful when I'm editing .vimrc
:source %
;; get the size of current file
:! du -sh %
;; etc, etc...
I would like to have similar functionality under emacs
(version 24, if that makes any difference), namely have an easy way to insert the name of the file opened in the current buffer.
**Examples of what I want to do**
*Here I describe some basic use cases as to explain better when I feel the need for such a shortcut*
1. Compile: When I enter M-x compile
emacs asks me for a compile command. I would like to enter gcc (current-buffer)
easily.
2. Load-file: When I'm editing my .emacs file, I would like to load it right away to test the changes. The way I do it is M-x load-file
and then I always spell out the name . e m a c s. I would like to have a shortcut.
3. Launch outside processes: I gave du -sh
as an example, only to illustrate that I want the shortcut to be also available when I execute shell commands with M-!
**What I found so far**
- This question here on U&L. The answers given are basically showing where to find the filename of a buffer so one can add it to the kill-ring. It's not exactly what I'm looking for, I don't want to have to manually kill the filename before I want to use it. (Also solutions described in both answers don't seem to work as smoothly in my emacs and require additional keystrokes making them a bit of a pain).
***EDIT**: A bit unrelated, by I found out why these solutions don't work. I have IDO enabled, for better or worse.*
- The (current-buffer)
function described in the manual does return the name of the file in the current buffer, but nowhere in the examples I gave above, am I evaluating elisp code. Is there a way to insert the result of the evaluation of this function in a (mini)buffer and binding this way to a shortcut?
**Am I wrong to think this way?**
I am currently learning to use emacs (it's been a few months actually) after years of using Vim. I want to avoid a predictable *using-emacs-in-a-Vim-way* trap. If you feel that what I'm asking for is not very *emacs-y*, and there should be a better (cleaner?) way to do it, please do mention it in your answers.
rahmu
(20511 rep)
Aug 9, 2012, 09:30 AM
• Last activity: Jul 18, 2025, 10:25 AM
0
votes
2
answers
222
views
How we can recursively expand inline functions and aliases inside function?
Nesting problem with duck typing: function f1 { echo $1; } #with argument function f2 { N=$((0+1)); f$N "fff"; } #with dynamic name Desired result: function f2 { { echo $1; } "fff"; } NB. sorry I revised the problemt to real codding issues. How to solve the issue?
Nesting problem with duck typing:
function f1 { echo $1; } #with argument
function f2 { N=$((0+1)); f$N "fff"; } #with dynamic name
Desired result:
function f2 { { echo $1; } "fff"; }
NB. sorry I revised the problemt to real codding issues.
How to solve the issue?
mr.tee
(119 rep)
Jun 21, 2023, 09:26 AM
• Last activity: Jul 9, 2025, 10:47 AM
49
votes
14
answers
40480
views
Executing a Bash Script Function with Sudo
I have a script that does a number of different things, most of which do not require any special privileges. However, one specific section, which I have contained within a function, needs root privileges. I don't wish to require the entire script to run as root, and I want to be able to call this fu...
I have a script that does a number of different things, most of which do not require any special privileges. However, one specific section, which I have contained within a function, needs root privileges.
I don't wish to require the entire script to run as root, and I want to be able to call this function, with root privileges, from within the script. Prompting for a password if necessary isn't an issue since it is mostly interactive anyway. However, when I try to use
sudo functionx
, I get:
sudo: functionx: command not found
As I expected, export
didn't make a difference. I'd like to be able to execute the function directly in the script rather than breaking it out and executing it as a separate script for a number of reasons.
Is there some way I can make my function "visible" to sudo without extracting it, finding the appropriate directory, and then executing it as a stand-alone script?
The function is about a page long itself and contains multiple strings, some double-quoted and some single-quoted. It is also dependent upon a menu function defined elsewhere in the main script.
I would only expect someone with sudo ANY to be able to run the function, as one of the things it does is change passwords.
BryKKan
(2267 rep)
Mar 11, 2016, 04:54 AM
• Last activity: Jul 2, 2025, 01:28 PM
8
votes
6
answers
15038
views
How to catch and handle nonzero exit status within a Bash function?
Say I have the following (pointless) Bash function: myfunc() { ls failfailfail uptime } I run it as follows: myfunc || echo "Something is wrong." What I want to happen is `ls` runs (as it should), `failfailfail` does not work (since it doesn't exist), and `uptime` doesn't run. The return value of th...
Say I have the following (pointless) Bash function:
myfunc() {
ls
failfailfail
uptime
}
I run it as follows:
myfunc || echo "Something is wrong."
What I want to happen is
ls
runs (as it should), failfailfail
does not work (since it doesn't exist), and uptime
doesn't run. The return value of the function would be nonzero, and the error message would be shown. The return value doesn't have to be the exact exit status of the failed command, it just shouldn't be zero.
What actually happens is I get the output of ls
, followed by "-bash: failfailfail: command not found", followed by the output of uptime
. The error message is not shown, because the failed exit status is getting eaten.
set -e
has no useful effect, either within the function or in the scope where the function is called. The only way I can get this to work the way I want is:
myfunc() {
ls || return $?
failfailfail || return $?
uptime || return $?
}
But this seems awfully repetitive and ugly. Is there another way to clean this up?
smitelli
(308 rep)
Apr 28, 2016, 04:15 PM
• Last activity: Jun 23, 2025, 08:08 PM
66
votes
5
answers
77077
views
What is "declare" in Bash?
After reading ilkkachu's answer to [this question][1] I learned on the existence of the `declare` (with argument `-n`) shell built in. `help declare` brings: > Set variable values and attributes. > > Declare variables and give them attributes. If no NAMEs are given, > display the attributes and valu...
After reading ilkkachu's answer to this question I learned on the existence of the
declare
(with argument -n
) shell built in.
help declare
brings:
> Set variable values and attributes.
>
> Declare variables and give them attributes. If no NAMEs are given,
> display the attributes and values of all variables.
> -n ... make NAME a reference to the variable named by its value
I ask for a general explanation with an example regarding declare
because I don't understand the man
. I know what is a variable and expanding it but I still miss the man
on declare
(variable attribute?).
Maybe you'd like to explain this based on the code by ilkkachu in the answer:
#!/bin/bash
function read_and_verify {
read -p "Please enter value for '$1': " tmp1
read -p "Please repeat the value to verify: " tmp2
if [ "$tmp1" != "$tmp2" ]; then
echo "Values unmatched. Please try again."; return 2
else
declare -n ref="$1"
ref=$tmp1
fi
}
user149572
Apr 3, 2019, 06:49 AM
• Last activity: Jun 11, 2025, 10:39 AM
0
votes
1
answers
32
views
How to keep a local function private in a zsh `autoload` module?
I want to define a helper function in a zsh `autoload`-ed module. The problem is, if I just define in my `my_autoloaded_fn` file such as ```zsh function helper { # ... } helper a helper b ``` the name `helper` will become defined in the global namespace once `my_autoloaded_fn` is invoked. I tried al...
I want to define a helper function in a zsh
autoload
-ed module. The problem is, if I just define in my my_autoloaded_fn
file such as
function helper {
# ...
}
helper a
helper b
the name helper
will become defined in the global namespace once my_autoloaded_fn
is invoked.
I tried also
local helper
function helper {
# ...
}
but the local
declaration seems to have no effect. And neither local -f
works.
Petr
(1776 rep)
May 19, 2025, 01:28 PM
2
votes
4
answers
165
views
Is there a Bash variable containing the name of the previously executed function?
I want to line up a couple of Bash functions based on the success or failure of the execution of the preceding function. If something fails, I want to print an error message: `function_x has failed`. **Example 1** ```bash function_x() { false } if ! function_x ; then echo "function_x has failed" els...
I want to line up a couple of Bash functions based on the success or failure of the execution of the preceding function.
If something fails, I want to print an error message:
function_x has failed
.
**Example 1**
function_x() {
false
}
if ! function_x ; then
echo "function_x has failed"
else
echo "call another function here"
fi
So the above works fine, but I would like to make the content of the error message more specific than above, maybe through the use of an environment variable carrying the name of the previously run function. Something like below:
**Example 2**
if ! function_x ; then
echo "${PREVIOUS_FUNCTION} has failed"
else
echo "call another function here"
fi
Now, my question is whether such a generic environment variable exists, or whether there is some other way to make that error message "function [function_name] has failed"
more generic than in Example 1.
vrms
(287 rep)
May 4, 2025, 04:33 AM
• Last activity: May 5, 2025, 10:57 AM
0
votes
0
answers
26
views
Why is set -e also ignored for functions called via command substitution
I've seen [questions][1] [about][2] this topic, but they talk about constructs like `if` or `||`. I don't understand why the same behavior seem to happen for substitution (`$()`)? ``` $ my_function() { echo "the following command could fail:"; false; echo "this is after the command that fails"; } $...
I've seen questions about this topic, but they talk about constructs like
if
or ||
.
I don't understand why the same behavior seem to happen for substitution ($()
)?
$ my_function() { echo "the following command could fail:"; false; echo "this is after the command that fails"; }
$ (set -ex; var=$(my_function); echo "$var" )
++ my_function
++ echo 'the following command could fail:'
++ false
++ echo 'this is after the command that fails'
+ var='the following command could fail:
this is after the command that fails'
+ echo 'the following command could fail:
this is after the command that fails'
the following command could fail:
this is after the command that fails
vs
$ my_function() { set -e; echo "the following command could fail:"; false; echo "this is after the command that fails"; }
$ (set -ex; var=$(my_function); echo "$var" )
++ my_function
++ set -e
++ echo 'the following command could fail:'
++ false
+ var='the following command could fail:'
errexit
seems to behave as expected for simple commands:
$ (set -ex; var=$(false); echo "$var" )
++ false
+ var=
If I use read
instead I get the expected behaviour:
$ my_function() { echo "the following command could fail:"; false; echo "this is after the command that fails"; }
$ (set -exo pipefail; my_function | read var; echo "$var" )
+ my_function
+ echo 'the following command could fail:'
+ read var
+ false
Jakub Bochenski
(325 rep)
Apr 29, 2025, 03:30 PM
• Last activity: Apr 29, 2025, 03:36 PM
4
votes
1
answers
218
views
Run in background avoiding any job control message from the shell
Lets define a shell function (here the shell is Bash) and test it $ s () { xterm -e sleep 5 & } $ s [1] 307926 $ [1]+ Done xterm -e sleep 5 $ With my specific meaning of *better*, I can redefine `s` like this $ s () { xterm -e sleep 5 & disown ; } $ s [1] 307932 $ $ (no message from the shell when t...
Lets define a shell function (here the shell is Bash) and test it
$ s () { xterm -e sleep 5 & }
$ s
307926
$
+ Done xterm -e sleep 5
$
With my specific meaning of *better*, I can redefine
s
like this
$ s () { xterm -e sleep 5 & disown ; }
$ s
307932
$
$
(no message from the shell when the job is finished).
Here I have to ask, is it possible to define s
so that I have
$ s () { pre_magic xterm -e sleep 5 post_magic ; }
$ s
$
$
i.e., suppress the job info printed on terminal by the shell?
gboffi
(1376 rep)
Apr 17, 2025, 01:52 PM
• Last activity: Apr 17, 2025, 02:21 PM
4
votes
3
answers
3615
views
How to prefix every argument with '-p' in Bash?
How do I prefix `-p` to every argument passed to my function? Modifying the arguments themselves and creating a new array are both fine.
How do I prefix
-p
to every argument passed to my function?
Modifying the arguments themselves and creating a new array are both fine.
user541686
(3163 rep)
Jul 14, 2011, 03:34 AM
• Last activity: Feb 22, 2025, 01:16 PM
88
votes
14
answers
51794
views
Why write an entire bash script in functions?
At work, I write bash scripts frequently. My supervisor has suggested that the entire script be broken into functions, similar to the following example: #!/bin/bash # Configure variables declare_variables() { noun=geese count=three } # Announce something i_am_foo() { echo "I am foo" sleep 0.5 echo "...
At work, I write bash scripts frequently. My supervisor has suggested that the entire script be broken into functions, similar to the following example:
#!/bin/bash
# Configure variables
declare_variables() {
noun=geese
count=three
}
# Announce something
i_am_foo() {
echo "I am foo"
sleep 0.5
echo "hear me roar!"
}
# Tell a joke
walk_into_bar() {
echo "So these ${count} ${noun} walk into a bar..."
}
# Emulate a pendulum clock for a bit
do_baz() {
for i in {1..6}; do
expr $i % 2 >/dev/null && echo "tick" || echo "tock"
sleep 1
done
}
# Establish run order
main() {
declare_variables
i_am_foo
walk_into_bar
do_baz
}
main
Is there any reason to do this other than "readability", which I think could be equally well established with a few more comments and some line spacing?
Does it make the script run more efficiently (I would actually expect the opposite, if anything), or does it make it easier to modify the code beyond the aforementioned readability potential? Or is it really just a stylistic preference?
Please note that although the script doesn't demonstrate it well, the "run order" of the functions in our actual scripts tends to be very linear --
walk_into_bar
depends on stuff that i_am_foo
has done, and do_baz
acts on stuff set up by walk_into_bar
-- so being able to arbitrarily swap the run order isn't something we would generally be doing. For example, you wouldn't suddenly want to put declare_variables
after walk_into_bar
, that would break things.
An example of how I would write the above script would be:
#!/bin/bash
# Configure variables
noun=geese
count=three
# Announce something
echo "I am foo"
sleep 0.5
echo "hear me roar!"
# Tell a joke
echo "So these ${count} ${noun} walk into a bar..."
# Emulate a pendulum clock for a bit
for i in {1..6}; do
expr $i % 2 >/dev/null && echo "tick" || echo "tock"
sleep 1
done
Doktor J
(2672 rep)
Sep 29, 2016, 06:45 PM
• Last activity: Jan 28, 2025, 10:11 PM
31
votes
9
answers
25704
views
How to set an alias on a per-directory basis?
Suppose you have an alias `go`, but want it to do different things in different directories? In one directory it should run `cmd1`, but in another directory it should run `cmd2` By the way, I have an aliases for switching to the above directories already, so is it possible to append the `go` alias a...
Suppose you have an alias
go
, but want it to do different things in different directories?
In one directory it should run cmd1
, but in another directory it should run cmd2
By the way, I have an aliases for switching to the above directories already, so is it possible to append the go
alias assignment to the foo
alias?
alias "foo=cd /path/to/foo"
Working in bash(?) on OSX.
B Seven
(8469 rep)
Oct 26, 2012, 06:54 PM
• Last activity: Jan 16, 2025, 11:43 AM
2
votes
2
answers
2630
views
Passing options/args/parameters with spaces from the script to a function within
I've got a script that I am passing arguments/options/parameters to at the command line. One of the values has a space in it, which I have put in double quotes. It might be easier to provide an example. Forgive my usage of arguments/options/parameters. $: ./test1.ksh -n -b -d "Home Videos" My proble...
I've got a script that I am passing arguments/options/parameters to at the command line. One of the values has a space in it, which I have put in double quotes. It might be easier to provide an example. Forgive my usage of arguments/options/parameters.
$: ./test1.ksh -n -b -d "Home Videos"
My problem is setting a variable to "Home Videos" and it being used together. In my example, the -d is to specify a directory. Not all the directories have spaces, but some do in my case.
This is an example of the code I have that is not working as expected:
#!/bin/ksh
Function1()
{
echo "Number of Args in Function1: $#"
echo "Function1 Args: $@"
SetArgs $*
}
SetArgs()
{
echo -e "\nNumber of Args in SetArgs: $#"
echo "SetArgs Args: $@"
while [ $# -gt 0 ]
do
case $1 in
-[dD])
shift
export DirectoryName=$1
;;
-[nN])
export Var1=No
shift
;;
-[bB])
export Var2=Backup
shift
;;
*)
shift
;;
esac
done
Function2
}
Function2()
{
echo "Directory Name: ${DirectoryName}"
}
Function1 $*
When I run this, I'm getting only Home for the DirectoryName instead of Home Videos. Seen below.
$ ./test1.ksh -n -b -d "Home Videos"
Number of Args in Function1: 5
Function1 Args: -n -b -d Home Videos
Number of Args in SetArgs: 5
SetArgs Args: -n -b -d Home Videos
Var1 is set to: No
Var2 is set to: Backup
Directory Name: Home
What I am expecting and I have not been able to get it to happen is:
$ ./test1.ksh -n -b -d "Home Videos"
Number of Args in Function1: 4
Function1 Args: -n -b -d "Home Videos"
Number of Args in SetArgs: 4
SetArgs Args: -n -b -d "Home Videos"
Var1 is set to: No
Var2 is set to: Backup
Directory Name: Home Videos <-- Without double quotes in the final usage.
I've tried escaping the double quotes, without any success.
DNadler
(23 rep)
Nov 21, 2017, 11:05 AM
• Last activity: Dec 31, 2024, 10:23 AM
7
votes
1
answers
579
views
bash - how to remove a local variable (inside a function)
I've read what's listed in Bibliography regarding `unset`, `declare`, `local` and "Shell Functions". My version of Bash is ``` GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu) ``` ``` var='outer' declare -p var unset var declare -p var function foo { echo \""I'm in"\" local var='inner' decl...
I've read what's listed in Bibliography regarding
unset
, declare
, local
and "Shell Functions".
My version of Bash is
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
var='outer'
declare -p var
unset var
declare -p var
function foo {
echo \""I'm in"\"
local var='inner'
declare -p var
unset var
declare -p var
}
foo
(the strange quoting around I'm in
is there just to preserve syntax highlithing in the following block quote.) This prints
declare -- var="outer"
bash: declare: var: not found
"I'm in"
declare -- var="inner"
declare -- var
There is a difference in unsetting a global variable and unsetting a local variable inside a function. In the former case, the variable is removed. In the latter, the variable stays declared (but unset).
Is there a way to completely remove a local variable inside a function (before the function returns)? That is that the output would be
declare -- var="outer"
bash: declare: var: not found
"I'm in"
declare -- var="inner"
bash: declare: var: not found
That would be useful to test if a variable is non existing inside a function, like in
function foo {
local var
while
declare -p var
do
echo "$var"
((var++))
[[ "$var" -eq 4 ]] \
&& unset var
done
}
This code loops indefinitely, printing
declare -- var="1"
1
declare -- var="2"
2
declare -- var="3"
3
declare -- var
declare -- var="1"
1
declare -- var="2"
2
declare -- var="3"
3
declare -- var
[omissis]
Is there anything wrong in checking if a variable exists using declare -p
?
The only mention I found in the Bash reference manual about the difference between unsetting a global variable and a local one is
> If a variable at the current local scope is unset, it will remain so (appearing as unset) until it is reset in that scope or until the function returns. (ref. Bash reference manual - sec. "Shell Functions")
where the word _appearing_ is the only clue.
**Bibliography**
+ [Bash reference manual] sec. "4 Shell Builtin Commands"
+ [What does unset do?]
the_eraser
(185 rep)
Dec 10, 2024, 02:09 PM
• Last activity: Dec 10, 2024, 05:34 PM
55
votes
4
answers
26335
views
what is the zsh equivalent of bash's export -f
So I started using `zsh`. I like it all right. It seems very cool and slick, and the fact that the current working directory and actual command line are on different lines is nice, but at the same time, I'm noticing that `zsh` can be a bit slower than `bash`, especially when printing text to the scr...
So I started using
zsh
. I like it all right. It seems very cool and slick, and the fact that the current working directory and actual command line are on different lines is nice, but at the same time, I'm noticing that zsh
can be a bit slower than bash
, especially when printing text to the screen.
The thing I liked best was the fact that zsh
was 'backward compatible' with all of the functions I defined in my .bashrc
.
One gripe though. The functions all work perfectly, but I can't figure out how the exporting system works.
I had some of those .bashrc
functions exported so that I could use them elsewhere, such as in scripts and external programs, with export -f
.
In zsh, exporting doesn't seem to even be talked about. Is it autoloading? Are those two things the same? I'm having a seriously hard time figuring that out.
ixtmixilix
(13520 rep)
Dec 25, 2012, 12:54 AM
• Last activity: Oct 21, 2024, 08:18 PM
2
votes
1
answers
196
views
Why does a 'pipe-to-awk' behave differently inside a function?
I'm using `alsa` to fiddle around with the volume on a Bluetooth speaker I have connected. It's a 1-speaker setup; just something to provide some background. I can 'get' the volume setting fm the CLI as follows: ```bash $ amixer sget Master Simple mixer control 'Master',0 Capabilities: pvolume pswit...
I'm using
alsa
to fiddle around with the volume on a Bluetooth speaker I have connected. It's a 1-speaker setup; just something to provide some background.
I can 'get' the volume setting fm the CLI as follows:
$ amixer sget Master
Simple mixer control 'Master',0
Capabilities: pvolume pswitch pswitch-joined
Playback channels: Front Left - Front Right
Limits: Playback 0 - 65536
Mono:
Front Left: Playback 22938 [35%] [on]
Front Right: Playback 22938 [35%] [on]
I can 'set' the volume fm the CLI as follows:
$ amixer sset Master 50%
Simple mixer control 'Master',0
Capabilities: pvolume pswitch pswitch-joined
Playback channels: Front Left - Front Right
Limits: Playback 0 - 65536
Mono:
Front Left: Playback 32768 [50%] [on]
Front Right: Playback 32768 [50%] [on]
I don't need all this *verbosity*, so I decided to create a function, and two aliases in my ~/.bashrc
file to reduce that. The function is not working as I expected:
From the CLI, this works fine:
$ amixer sget Master | awk -F"[][]" '/Right:/ { print $2 }'
35%
But when I put this into my function statement in ~/.bashrc
, it works ***differently***:
# functions & aliases for alsa mixer/volume control
function vol-get() {
amixer sget Master | awk -F"[][]" '/Left:/ { print $2 }'
}
export -f vol-get
alias vol-up='amixer sset Master 5%+ > /dev/null && vol-get'
alias vol-dn='amixer sset Master 5%- > /dev/null && vol-get'
Re-reading ~/.bashrc
& running the vol-get
function yields the following:
$ . ~/.bashrc
$ vol-get
Front Left: Playback 22938 [35%] [on]
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ?? what happened here ??
$ vol-up
Front Left: Playback 26215 [40%] [on]
$
So - I'm *close*, but I don't understand why my | awk ...
behaves differently inside the function than it does on the command line. Can someone explain and correct this?
---
### Edits for answers to some of the Questions raised in the comments:
#### EDIT #1:
$ command -V vol-get
vol-get is a function
vol-get ()
{
amixer sget Master | awk -F"[][]" '/Left:/ { print $2 }'
}
$ awk --version
awk: not an option: --version
$ man awk
# reveals that I am actually calling mawk
, Version 1.3.4
#### EDIT #2:
RE: non-printing characters; note this is a partial c&p from the output (i.e. verbatim):
$ cat -vet ~/.bashrc
...
function vol-get() {$
amixer sget Master | awk -F'[][]' '/Left:/ { print $2 }'$
}$
...
Seamus
(3772 rep)
Oct 19, 2024, 07:21 AM
• Last activity: Oct 20, 2024, 09:46 PM
73
votes
6
answers
91433
views
Scope of Local Variables in Shell Functions
After reading [24.2. Local Variables](http://tldp.org/LDP/abs/html/localvar.html), I thought that declaring a variable `var` with the keyword `local` meant that `var`'s value was only accessible within the block of code delimited by the curly braces of a function. However, after running the followin...
After reading [24.2. Local Variables](http://tldp.org/LDP/abs/html/localvar.html) , I thought that declaring a variable
var
with the keyword local
meant that var
's value was only accessible within the block of code delimited by the curly braces of a function.
However, after running the following example, I found out that var
can also be accessed, read and written from the functions invoked by that block of code -- i.e. even though var
is declared local
to outerFunc
, innerFunc
is still able to read it and alter its value.
[**Run It Online**](http://www.tutorialspoint.com/execute_bash_online.php?PID=0Bw_CjBb95KQMd1ptTmpoOWUyS3M)
#!/usr/bin/env bash
function innerFunc() {
var='new value'
echo "innerFunc: [var:${var}]"
}
function outerFunc() {
local var='initial value'
echo "outerFunc: before innerFunc: [var:${var}]"
innerFunc
echo "outerFunc: after innerFunc: [var:${var}]"
}
echo "global: before outerFunc: [var:${var}]"
outerFunc
echo "global: after outerFunc: [var:${var}]"
Output:
global: before outerFunc: [var:] # as expected, var
is not accessible outside of outerFunc
outerFunc: before innerFunc: [var:initial value]
innerFunc: [var:new value] # innerFunc
has access to var
??
outerFunc: after innerFunc: [var:new value] # the modification of var
by innerFunc
is visible to outerFunc
??
global: after outerFunc: [var:]
**Q: Is that a bug in my shell (bash 4.3.42, Ubuntu 16.04, 64bit) or is it the expected behavior ?**
**EDIT:** Solved. As noted by @MarkPlotnick, this is indeed the expected behavior.
maddouri
(831 rep)
May 11, 2016, 04:22 PM
• Last activity: Oct 18, 2024, 07:07 PM
24
votes
3
answers
56364
views
Bash Scripting echo locally in a function
In bash scripts I try to keep my variables local to functions wherever I can and then pass what I need out of functions like bellow #!/bin/bash function FUNCTION() { local LOCAL="value" echo "$LOCAL" # return this variable } GLOBAL=$(FUNCTION) echo "$GLOBAL" But is it possible to do this while inclu...
In bash scripts I try to keep my variables local to functions wherever I can and then pass what I need out of functions like bellow
#!/bin/bash
function FUNCTION() {
local LOCAL="value"
echo "$LOCAL" # return this variable
}
GLOBAL=$(FUNCTION)
echo "$GLOBAL"
But is it possible to do this while including the function's own echos so that if the function has it's own messages to output I don't have to catch them in a variable
#!/bin/bash
function FUNCTION() {
local LOCAL="value"
echo "$LOCAL" # return this variable
echo "This function is done now" # do not return this variable
}
GLOBAL=$(FUNCTION)
echo "$GLOBAL" # should only echo 'value'
TheLovelySausage
(4443 rep)
Oct 15, 2015, 11:07 AM
• Last activity: Oct 17, 2024, 08:38 AM
3
votes
1
answers
564
views
Strange variable scope behavior when calling function recursivly
EDIT: sorry. this is my first question here. Here is a minimal working example ``` #!/bin/bash # count=0 function something() { if test -f "$1"; then # is a file ((count++)) echo $count $1 elif test -d "$1"; then # is a folder find $1 | while read line; do if [ $1 != $line ]; then # first line in fi...
EDIT: sorry. this is my first question here.
Here is a minimal working example
#!/bin/bash
#
count=0
function something() {
if test -f "$1"; then
# is a file
((count++))
echo $count $1
elif test -d "$1"; then
# is a folder
find $1 | while read line; do
if [ $1 != $line ]; then # first line in find is the folder itself. prevent infinte recursion
something $line
fi
done
fi
}
while [ $# -gt 0 ]
do
something "$1"
shift
done
echo "Processed $count files"
Example output:
$ ./test.sh *
1 0/file1.txt
2 0/file2.txt
1 1/file1.txt
2 1/file2.txt
1 2/file1.txt
2 2/file2.txt
1 3/file1.txt
2 3/file2.txt
1 4/file1.txt
2 4/file2.txt
1 5/file1.txt
2 5/file2.txt
1 6/file1.txt
2 6/file2.txt
1 7/file1.txt
2 7/file2.txt
1 8/file1.txt
2 8/file2.txt
1 9/file1.txt
2 9/file2.txt
1 test.sh
Processed 1 files
As you can see each time I call the function recursively it returns to the variable state on parent function and messes up the count.
Using Ubuntu 22.06 on WSL2 VM
Shlomo V
(43 rep)
Sep 3, 2024, 07:39 PM
• Last activity: Sep 4, 2024, 01:24 PM
Showing page 1 of 20 total questions