Unix & Linux Stack Exchange
Q&A for users of Linux, FreeBSD and other Unix-like operating systems
Latest Questions
9
votes
4
answers
22596
views
How to read the user input line by line until Ctrl+D and include the line where Ctrl+D was typed
This script takes the user input line after line, and executes `myfunction` on every line #!/bin/bash SENTENCE="" while read word do myfunction $word" done echo $SENTENCE To stop the input, the user has to press `[ENTER]` and then `Ctrl+D`. How can I rebuild my script to end only with `Ctrl+D` and p...
This script takes the user input line after line, and executes
myfunction
on every line
#!/bin/bash
SENTENCE=""
while read word
do
myfunction $word"
done
echo $SENTENCE
To stop the input, the user has to press [ENTER]
and then Ctrl+D
.
How can I rebuild my script to end only with Ctrl+D
and process the line where Ctrl+D
was pressed.
user123456
(5258 rep)
Oct 13, 2016, 06:58 PM
• Last activity: Apr 11, 2025, 05:29 AM
0
votes
2
answers
173
views
Systemd-user-service to enable keyboard gives no error but doesn't work
I have a bad laptop keyboard and a much better Lily58, so I wrote a bash-script to be able to disable my laptop keyboard so I can place the Lily58 on it and re-enable it after. But when I disable the laptop keyboard, it stays disabled if I put the laptop in suspension while I would prefer it to be a...
I have a bad laptop keyboard and a much better Lily58, so I wrote a bash-script to be able to disable my laptop keyboard so I can place the Lily58 on it and re-enable it after. But when I disable the laptop keyboard, it stays disabled if I put the laptop in suspension while I would prefer it to be automatically re-enabled on resume. So I wrote a short bash script
#!/bin/bash
fconfig="/home/alex/.keyboard"
id=$(xinput | grep AT | sed -n '2,2p' | awk '{print $7}' | sed 's/[^0-9]*//g')
if [ -f $fconfig ]; then
read -r var $fconfig
fi
fi
This checks whether "disabled" is in the file /home/alex/.keyboard
that tracks whether the keyboard is enabled, and if so runs xinput
to re-enable using the id it got by sifting through the output of xinput
in the manner used in the definition of id
, then set /home/alex/.keyboard
to enabled
. This works as it should when I trigger the bash-script from the terminal, but when I start the systemd-service
[Unit]
Description=This service enables your keyboard after suspension
PartOf=graphical-session.target
[Service]
Type=oneshot
ExecStart=/home/alex/bash/enable-keyboard
[Install]
WantedBy=multi-user.target
that I want to run after suspend, it sets /home/alex/.keyboard
to enabled
but does not actually re-enable my keyboard. Moreover, journalctl -xeu enable-keyboard.service
indicates no error:
Jul 17 22:16:25 gentoolaptop systemd: Starting This service enables your keyboard after suspension.
░░ Subject: A start job for unit UNIT has begun execution
░░ Defined-By: systemd
░░ Support: https://gentoo.org/support/
░░
░░ A start job for unit UNIT has begun execution.
░░
░░ The job identifier is 8969.
Jul 17 22:16:25 gentoolaptop systemd: Finished This service enables your keyboard after suspension.
░░ Subject: A start job for unit UNIT has finished successfully
░░ Defined-By: systemd
░░ Support: https://gentoo.org/support/
░░
░░ A start job for unit UNIT has finished successfully.
░░
░░ The job identifier is 8969.
What is going wrong?
Edit: If I put a clause into the script to print the output of xinput
into a file, the output consists of one empty line.
Edit: the output of systemctl --user status dbus.socket dbus.service
is
● dbus.socket - D-Bus User Message Bus Socket
Loaded: loaded (/usr/lib/systemd/user/dbus.socket; static)
Active: active (running) since Thu 2024-07-18 17:22:54 CEST; 5 days ago
Triggers: ● dbus.service
Listen: /run/user/1000/bus (Stream)
Tasks: 0 (limit: 47295)
Memory: 4.0K (peak: 1.5M)
CPU: 8ms
CGroup: /user.slice/user-1000.slice/user@1000.service/app.slice/dbus.socket
Jul 18 17:22:54 gentoolaptop systemd: Starting D-Bus User Message Bus Socket...
Jul 18 17:22:54 gentoolaptop systemd: Listening on D-Bus User Message Bus Socket.
● dbus.service - D-Bus User Message Bus
Loaded: loaded (/usr/lib/systemd/user/dbus.service; static)
Active: active (running) since Thu 2024-07-18 17:22:54 CEST; 5 days ago
TriggeredBy: ● dbus.socket
Docs: man:dbus-daemon(1)
Main PID: 897 (dbus-daemon)
Tasks: 1 (limit: 47295)
Memory: 1.0M (peak: 1.7M)
CPU: 252ms
CGroup: /user.slice/user-1000.slice/user@1000.service/session.slice/dbus.service
└─897 /usr/bin/dbus-daemon --session --address=systemd: --nofork --nopidfile --systemd-activation --syslog-only
Jul 23 16:55:45 gentoolaptop dbus-daemon: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.149' (uid=1000 pid=105378 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 23 17:11:00 gentoolaptop dbus-daemon: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
Jul 23 17:19:31 gentoolaptop dbus-daemon: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.152' (uid=1000 pid=106706 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 23 17:21:31 gentoolaptop dbus-daemon: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
Jul 23 17:30:31 gentoolaptop dbus-daemon: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.153' (uid=1000 pid=108520 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 23 17:32:31 gentoolaptop dbus-daemon: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
Jul 24 14:15:05 gentoolaptop dbus-daemon: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.164' (uid=1000 pid=126615 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 24 14:17:05 gentoolaptop dbus-daemon: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
Jul 24 14:26:05 gentoolaptop dbus-daemon: [session uid=1000 pid=897 pidfd=5] Activating via systemd: service name='org.freedesktop.Notifications' unit='dunst.service' requested by ':1.165' (uid=1000 pid=127823 comm="/bin/dunstify Battery <80 Battery under 80%.")
Jul 24 14:28:05 gentoolaptop dbus-daemon: [session uid=1000 pid=897 pidfd=5] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
The output of ls -l /run/user/*/bus
is
srw-rw-rw- 1 alex alex 0 2024-07-18 17:22 /run/user/1000/bus
.
Alexander Praehauser
(221 rep)
Jul 17, 2024, 08:30 PM
• Last activity: Jul 24, 2024, 04:26 PM
0
votes
1
answers
73
views
Displays a user input pop-up on the Android screen
Currently I'm interested in **Bash** and also the Android phone I have... I'm wondering if there is a way to display popup as text input on the android screen and then receive data from that user-submitted input using `adb` or using a root shell/bash script? For example, I created a bash script that...
Currently I'm interested in **Bash** and also the Android phone I have...
I'm wondering if there is a way to display popup as text input on the android screen and then receive data from that user-submitted input using
adb
or using a root shell/bash script?
For example, I created a bash script that will display the output Hello $userinput !!
When I run this bash script, a dialog will appear entitled ***What's Your Name?*** and I can fill it directly without going through the *terminal*...
Does anyone know how to do it?
**It would be nice if you could also tell it the same way but this is only for normal popup that don't contain any input boxes, but just like regular popup on Android* 😃
I'm currently very curious about things like this, I mean bash script, root shell or adb shell
command that can interact directly with user using the Android screen.
I'm using an Android 13 and have *root access* using Magisk
, the ROM installed is MIUI 14
TuanHaxor
(73 rep)
Feb 3, 2024, 04:26 PM
• Last activity: Feb 3, 2024, 07:32 PM
1
votes
0
answers
47
views
How do I request a user input with GUI from script running as root by modern initialization system?
I have Systemd service of type "oneshot" to be launched by Udev upon a device insertion. Service is launching shell script as root. The script needs user input in order to do it's job as intended. User is logged into GUI session (it's Xorg for now and a while, but not obligatory). How do a process r...
I have Systemd service of type "oneshot" to be launched by Udev upon a device insertion. Service is launching shell script as root. The script needs user input in order to do it's job as intended. User is logged into GUI session (it's Xorg for now and a while, but not obligatory).
How do a process running as root may request an input from a regular, current active user running GUI session? What about if it's sensitive data or when data is not? And what about if it's **not** Xorg?
One way to get data into variable is the following part of the script:
#!/bin/bash
while read session_id login ; do
if [ "$( loginctl show-session -p State "${session_id}" )" == "State=active" ]
then
break
fi
done <<< "$( loginctl list-sessions --no-legend | awk '{print $1 " " $3}' )"
if [ -n "${login}" ] ; then
string="$( DISPLAY=:0.0 \
XAUTHORITY="/home/${login}/.Xauthority" \
zenity --entry )"
else
echo "WARNING:${0}: Do nothing as no one logged in."
exit
fi
But it needs complex evaluation of DISPLAY, for example. And it's Xorg only?
What is a best way to do it with regular tools for Linux?
Thank you!
Asc
(11 rep)
Sep 1, 2023, 09:29 PM
• Last activity: Sep 1, 2023, 09:51 PM
4
votes
2
answers
3155
views
zsh script prompt reading single keystroke: add newline when appropriate?
I have a script that takes an `-i` flag (→ `$interactive`) and if set, asks a yes/no-default-no question for each target, à la `rm -i` and others. Zsh’s `read -q` is designed for this exact case—it accepts a single key and sets the variable to `y` if the key was y or Y , otherwise setting it to...
I have a script that takes an
-i
flag (→ $interactive
) and if set, asks a yes/no-default-no question for each target, à la rm -i
and others.
Zsh’s read -q
is designed for this exact case—it accepts a single key and sets the variable to y
if the key was y or Y, otherwise setting it to n
.
My issue is that I’m doing the prompt in a loop. So, by itself, it would print my prompt repeatedly on the same line. That is, this code:
# moshPids is an array of pids
for p in $moshPids; do
if [[ -n $interactive ]]; then
read -q "answer?Kill $p? (N/y)"
[[ "${answer}" == 'n' ]] && continue
fi
# do_kill set to print “killing $1” in debug
do_kill $p
done
results in:
$ myCmd
Kill 123? (N/y)nKill 456? (N/y)nKill 789? (N/y)yKilling 789
$
There are many solutions to this—some in answers on this very site—such as including a newline in the prompt, as so:
for p in $moshPids; do
if [[ -n $interactive ]]; then
read -q "answer?Kill $p? (N/y)
"
[[ "${answer}" == 'n' ]] && continue
fi
do_kill $p
done
which results in:
$ myCmd
Kill 123? (N/y)
nKill 456? (N/y)
nKill 789? (N/y)
yKilling 789
$
This seems ugly to me. Another solution is adding echo >&2
after the read
command, which—at least at first—seems perfect:
$ myCmd
Kill 123? (N/y)n
Kill 456? (N/y)y
Killing 456
Kill 789? (N/y)n
$
However, if you accept the default with ⏎, you get blank lines (⏎
not shown in actual output, but added to show input):
$ myCmd
Kill 123? (N/y)⏎
Kill 456? (N/y)y
Killing 456
Kill 789? (N/y)⏎
$
### Criteria
So: I want a single-key response that:
- Doesn’t result in multiple prompts/answers printed on a single line
- Doesn’t result in blank lines when ⏎ is pressed to accept defaults
- Still preserves the behavior of read -q
: sets answer
to y
if the key was y or Y; otherwise sets it to n
.
### Solution 1
Here’s my first solution:
for p in $moshPids; do
if [[ -n $interactive ]]; then
read -k1 "answer?Kill $p? (N/y)"
[[ $answer != $'\n' ]] && echo >&2
[[ "${answer}" =~ '[yY]' ]] || continue
fi
do_kill $p
done
Here, -k1
instead of -q
is passed to read
so that it instead gets the behavior of “read one character, any character”. That way, I can test for the character matching newline. If it doesn’t ($answer != $'\n'
), I can just print the missing newline.
But now $answer
will be set to any pressed key, not just to y
or n
. So we must check for y
or Y
("${answer}" =~ '[yY]'
).
Is there a better way to handle this?
### Solution 2
I've also thought about this, using stty
calls to temporarily disable keyboard echoing:
zsh
for p in $moshPids; do
if [[ -n $interactive ]]; then
stty -echo
read -q "answer?Kill $p? (N/y)"
stty echo
echo >&2
[[ "${answer}" == 'n' ]] && continue
fi
do_kill $p
done
which, by disabling the visibility of the keyed response, may or may not be preferable depending on whether you're prioritizing pretty output or being able to see the input in scrollback. (In this case, of a yes/no question where the yes option always prints something, it seems fine to noecho. One could always add an echo -n "${answer}"
after the read
if desired, with some sort of expansion incantation to turn newline into a blank.)
It's a line longer than the first solution, but is perhaps easier to understand since it uses read -q
so doesn't have to test against a regex, and unconditionally echos the newline.
But on the other hand, it _does_ monkey with the terminal; I’ve put the two commands close enough to each other than there shouldn’t be _too_ large a time window for command interruption to result in terminal insanity, but it is still a concern. (Also, for completeness, I should add a check that -i
isn’t being called non-interactively—otherwise, the stty
and read
operations will fail.)
Are there any even better or more idiomatic solutions than the two I've presented? This seems like an obvious behavior that many "-i
for interactive" commands (most written in something other than the shell, of course) follow.
Trey
(292 rep)
Feb 3, 2020, 10:49 PM
• Last activity: Jun 14, 2023, 02:37 PM
0
votes
2
answers
567
views
Source script with user input
I have a script that is something like ```bash #!/bin/bash echo -n "User: " read -e username echo -n "Password: " read -es password export http_proxy="http://$username:$password@localhost:40080" export https_proxy="http://$username:$password@localhost:40080" $@ unset http_proxy unset https_proxy ```...
I have a script that is something like
#!/bin/bash
echo -n "User: "
read -e username
echo -n "Password: "
read -es password
export http_proxy="http://$username:$password@localhost:40080"
export https_proxy="http://$username:$password@localhost:40080"
$@
unset http_proxy
unset https_proxy
It reads the user/pass, export the proxy, run the command I need the proxy then clean it.
It works. But I tried making this:
#!/bin/bash
echo -n "User: "
read -e username
echo -n "Password: "
read -es password
export http_proxy="http://$username:$password@localhost:40080"
export https_proxy="http://$username:$password@localhost:40080"
So I could source proxyscript
(and be able to use the proxy for a whole session without needing to put user/pass everytime), it waits for input, but exports http://:@localhost:40080
---
So, what I'm doing wrong or how can I make it work?
(I know I can make it as args and use $1
/$2
, or something like that, but I would like to avoid having to have the password open in the history)
---
Edit/Solution:
Building on the answers, a small change was enough to make it compatible with both bash
and zsh
:
#!/bin/bash
echo -n "User: "
read username
echo -n "Password: "
read -s password
export http_proxy="http://$username:$password@localhost:40080"
export https_proxy="http://$username:$password@localhost:40080"
Basically, just removed the e
flag.
Noriller
(111 rep)
Sep 14, 2022, 01:17 PM
• Last activity: Sep 14, 2022, 02:26 PM
4
votes
1
answers
659
views
Put a specific file in every Unix user's home directory when they're created and added to a particular group
How can I set up my Solaris system so that every time a user is created and assigned to a specific group, a specific file is placed in that user's home directory?
How can I set up my Solaris system so that every time a user is created and assigned to a specific group, a specific file is placed in that user's home directory?
Nestor
(41 rep)
Aug 18, 2022, 08:00 AM
• Last activity: Aug 19, 2022, 03:35 AM
6
votes
2
answers
57668
views
Bash script - Automatically enter user input (password of keystore)
I know this has been asked before but almost only workarounds have been provided. None that solved my problem just yet. I'm trying to create my own `.sh` file which will generate an `apk`. After using jarsigner it asks for a password of my keystore. Now the security on this part doesn't play a role...
I know this has been asked before but almost only workarounds have been provided. None that solved my problem just yet.
I'm trying to create my own
.sh
file which will generate an apk
. After using jarsigner it asks for a password of my keystore. Now the security on this part doesn't play a role a.t.m. so I was just wondering, how can I (either remove the password of my .keystore
file or enter the password as plain text) achieve this?
The full command:
jarsigner -sigalg SHA1withRSA -digestalg SHA1 -verbose -keystore keyForApk.keystore
apk/android-release-unsigned.apk alias_name
Where it then prompts me the following:
Enter Passphrase for keystore:
Now via which command can I enter this dynamically after the jarsigner command?
Ivafo
(161 rep)
Oct 17, 2016, 12:35 PM
• Last activity: Feb 25, 2022, 11:23 AM
1
votes
1
answers
419
views
Read file from user input with a list of prefixes, then call file with prefixes in while loops
I am trying to direct user input file into while loop, but kept on failing when ran the script. The user input file `genelist` contained a list of numbers where I have been using as prefixes of my other files. Eg. 012.laln, 012.model. genelist: 012 013 025 039 109 . . . This is the script I have bee...
I am trying to direct user input file into while loop, but kept on failing when ran the script.
The user input file
genelist
contained a list of numbers where I have been using as prefixes of my other files. Eg. 012.laln, 012.model.
genelist:
012
013
025
039
109
.
.
.
This is the script I have been testing on.
#!/usr/bin/env bash
read -pr "genefile: " genelist
read -pr "treefile: " trees
read -pr "workers: " workers
while read -r i; do
while read -r j; do
raxml-ng --sitelh --msa "$i".laln --model "$j".model --tree "${trees}" --workers "${workers}" --prefix "$i"-rT;
done < "$genelist".model;
done < "$genelist"
In order to execute raxml-ng tool, I need to input files for --msa, --model, --tree, --workers and --prefix for output file name. I need to repeat the process with multiple files, each 012.laln need to match with 012.model and generate output file named 012-rT. The input files for tree and workers are the same for all the files.
I kept on getting error:
line 2: read: `genefile: ': not a valid identifier
line 3: read: `treefile: ': not a valid identifier
line 4: read: `workers: ': not a valid identifier
Modifying the way I call the user input file "genelist" in a few ways but with no avail.
while read -r "${genelist}" ...
while read -r "${genelist{@}}" ...
while read -r "{genelist}" ...
Before this, I have been using for loops, i.e., the one-liner below. It worked well.
I would like to try on while loops if possible.
for i in $(cat genelist); do for j in $(cat $i.model); do raxml-ng --sitelh --msa $i.laln.trgc38_1l --model $j --tree trees --workers 4 --prefix $i-rT; done; done
Questions:
What is the correct and neat way to call the user input file genelist
into the while loops?
There are some example I found in here but those are using numbers/number sequences in the loops. The answers suggested using C in for/while loops to solve the issue. But that doesn't seemed to be relevant for my case.
Meanwhile, any better alternative for for/while loops in this case is also welcome!
web
(193 rep)
Nov 16, 2021, 03:33 PM
• Last activity: Nov 17, 2021, 09:37 AM
0
votes
1
answers
2046
views
How can I take multiple inputs from a user and convert to a string that looks up values and adds them to a variable?
I have a script that takes input from a user (options 1, 2, 3, etc.) to choose files to deploy to a remote server. Instead of the user running this script multiple times, I would like for them to be able to input multiple options (ex. 2,3) and as a result, those entries would add text to a variable...
I have a script that takes input from a user (options 1, 2, 3, etc.) to choose files to deploy to a remote server. Instead of the user running this script multiple times, I would like for them to be able to input multiple options (ex. 2,3) and as a result, those entries would add text to a variable that is then referenced in the main function.
I have tried summing these and having input match the sum, however, if we have many artifacts to put in this list, option 5 would deploy one thing and options 2,3 would deploy differently, but added together would deploy the same as option 5 which is not acceptable.
For instance this is what I have currently setup I am just matching the string input from the user (after dropping spaces, if any) and running that option. This is OK for only 2 or 3 artifacts, however, when the list gets long the choices get exponentially greater.
#!/bin/sh
export alltags="all"
export tag1="artifact1"
export tag2="artifact2"
export tag3="artifact3"
deployment_tag=""
function updateArtifacts
{
cp -r /path/to/artifact/artifact.zip --tags "\"${deployment_tag}"\"
}
echo "Enter the number of the artifacts you would like to deploy"
"1. artifact1"
"2. artifact2"
"3. artifact3"
read -p " " num
trimNum=
echo $num | sed 's/ //g'
if [ "$trimNum" == "1" ]; then
$deployment_tag+="$alltags"
echo "Updating all artifacts"
updateArtifacts
elif [ "$trimNum" == "2" ]; then
$deployment_tag+="$tag1"
echo "Updating artifact 1"
updateArtifacts
elif [ "$trimNum" == "2,3" ]; then
$deployment_tag+="$tag1,$tag2"
echo "Updating artifact 1 and 2"
updateArtifacts
else
echo "aborted, please enter a valid selection"
fi
I know I am missing options, but this is just to give a brief example. I know this is long winded, I appreciate any input.
oakenshield
(3 rep)
Jul 1, 2021, 02:22 PM
• Last activity: Jul 2, 2021, 04:53 AM
1
votes
1
answers
3729
views
Set variables via user input and check all variables have been set before continuing script
I'm building an automated bash script that will install and configure several packages on a Linux Server. I'm hoping to re-use this script on multiple servers but change some parameters accustom to the needs. So that I don't have to go through lots of code in the future making multiple changes using...
I'm building an automated bash script that will install and configure several packages on a Linux Server.
I'm hoping to re-use this script on multiple servers but change some parameters accustom to the needs. So that I don't have to go through lots of code in the future making multiple changes using find and replace, I've used variables throughout the script as they can simply have their values defined at the top/beginning of the script.
As some of the variables are passwords I want to avoid storing the passwords in a plain text file. My way around this is to have the variable values stored in encrypted document which I can read from and then define the variables at the beginning of the script. This will be done by running through a series of questions and asking me for my input to set the values for the variables. I've worked out how to do this using the following commands:
`
read -p "echo -e 'Enter admin user password: \n\b'
" admin_user_password
echo "You entered '$admin_user_password"
`
The area that gets tricky in regards to bash script writing is, I would like to ensure all of the variables are set (not left blank) and ensure they are entered correctly before the script can continue and automatically do its own thing. Setting the variables at the beginning is the only part of the script that requires user interactivity. In order to get this to work, I'm fairly certain I will be looking at loops.
This is the order I'm hoping to run the loop(s) before the automated section of the script starts.
1. The script asks for variables by asking for users input
2. The user set variables will be checked against a list of all the variables. Any variables not entered/set in step 1 will run through the remaining questions warning the user "you have not set a value for $some-variable".
3. Once all of the variables are set it will then print out all of the set variables and their values and ask if they are correct with a simple yes/no. If they are not correct I want to return to step 1 again to re-run through the question. However, if the variables and values are correct the script will continue into the automated section.
This is what I have so far.
`
## TOP OF SCRIPT ##
script_variables=(
admin_user_name
admin_user_password
)
for i in "${script_variables[@]}"; do
read -p "echo -e 'Enter value for: \n\b'
" ${script_variables[@]}
echo "You entered '${script_variables[@]}'"
if test -z "${script_variables[@]}"
then
echo "${script_variables[@]} has not been set"
# loopback to the top of the script
continue
else
while true; do
read -p "Are the variables ccorrect?" yn
case $yn in
[Yy]* ) echo "All variables have been set. The script will now continue."; sleep 2; break;;
[Nn]* ) continue;;
* ) echo "Please answer yes or no.";;
esac
fi
done
# Automated script commands below
`
I'm not sure if the above commands will work. Even if it does where continue
is on line 14, where the loop will return to the ## TOP OF SCRIPT ## section it will ask me all of the questions in the array again. On the second pass of asking me the questions it needs to check itself if the variables have been set. For those variables that have not been set, it should be the only questions I get re-asked.
The only way I could possibly do it is to put the variable testing section at the beginning. This will just mean that on the first instance of being asked the questions to set the variables I will get a message to say that none of the variables have been set.
The reason I'm asking for help is I rarely deal with loops. My Unix knowledge is solely self-taught mostly through looking on the internet on forums like this one or experimenting with the commands on Linux PC in a virtual environment, and I haven't ventured into the depths of loops yet. Anytime I have used loops, they are snippets I've taken from the internet and used in my own scripts. Obviously with my script above I'm looking at nested loops and that increases the complexity even further.
**Update 1**
In regards to your brilliant answers, I want to tweak the displayed text so when entering the variables it is entered on a new line below.
For example, how would I place a line break in the
`
read -p ("Enter value for $varName \n\b " script_variables[$varName]
`
I want to display something like this:
`
Enter value for admin_user_name
>
`
I saw to guides on the internet talking about using echo -e
so that \n\b
could be used. I did have a play around but the variables weren't expanding.
https://stackoverflow.com/questions/8467424/echo-newline-in-bash-prints-literal-n
**UPDATE 2**
I'm thinking of expanding your script and implementing an optional way of reading and storing the variables to and from a temporary file. I will be able to keep this safe from other system users by setting appropriate Unix permissions and then I'm going to delete the file at then very end of the script so there are not traces of it.
At the beginning of the script I would like to check if a specific text file containing the variables exists. If the file does exist then check if all of the variables have been set and compare against the array of variable names. If the stored variables in the file are not complete, run through the loop until they are set. Obviously the variables stored in the file will be set only if the user has said to "yes" when they are asked "are you sure this is correct?"
N.B once I have got this script working I am hoping to place it on GitHub and update my answer on here with the final version so that others can use it, as it is bound to help others out.
willowen100
(67 rep)
Sep 27, 2020, 10:41 AM
• Last activity: Nov 27, 2020, 08:23 AM
0
votes
1
answers
745
views
why perl's if condition is satisfying empty string?
The below code works fine, except for the part the STDIN takes an empty value also and goes to first selection `"print "Selected Y \n";"`. If I use `&& $check ne "" ) {` after `/^[Y]?$/i`, the issue with empty STDIN also solves. But the question is why empty value passes there? my $check = 'NULL'; w...
The below code works fine, except for the part the STDIN takes an empty value also and goes to first selection
"print "Selected Y \n";"
. If I use && $check ne "" ) {
after /^[Y]?$/i
, the issue with empty STDIN also solves. But the question is why empty value passes there?
my $check = 'NULL';
while ( $check eq 'NULL' ) {
print "Do you wish to continue? (Y/N)\n\n";
print "Enter Selection: ";
chomp ( $check = );
if ( $check =~ /^[Y]?$/i ) {
print "Selected Y \n";
}
elsif ( $check =~ /^[N]$/i ) {
print "Selected N \n";
}
else {
print "\nInvalid input, please re-enter selection. (Y/N) \n\n";
$check = 'NULL';
}
I am new to perl, can someone help me understand the behavior?
prado
(960 rep)
Nov 18, 2020, 07:16 AM
• Last activity: Nov 18, 2020, 09:16 AM
2
votes
2
answers
3125
views
Read from terminal without waiting for [ENTER]
I'm sorry to bother you with such silly questions, but I recently started working with the Linux terminal and when I was reading a paper about the command `stty` I found the following question: > ¿How can you change the echo and read without waiting for ENTER (simply by entering a hexadecimal d...
I'm sorry to bother you with such silly questions, but I recently started working with the Linux terminal and when I was reading a paper about the command
stty
I found the following question:
> ¿How can you change the echo and read without waiting for ENTER (simply by entering a hexadecimal digit from "0" to "f")?
I know that the first part stty -echo
and stty echo
.
But I have no clue of how to do read from terminal without waiting for ENTER.
I have been searching in the man
the second one and I cannot find in the command stty
the settings to make this posible.
I know it should be something simple but I can't find a solution or logic to the addition of entering a hexadecimal digit.
Commodore
(21 rep)
Nov 2, 2020, 08:32 AM
• Last activity: Nov 2, 2020, 12:36 PM
8
votes
2
answers
7304
views
bash script - request input via gui
I'm currently writing a nemo action script in bash, and I need a way to get input from the user. How?, the terminal isn't showing when running an action script. is there anyway to popup a query window in the GUI to ask the user for input?
I'm currently writing a nemo action script in bash, and I need a way to get input from the user.
How?, the terminal isn't showing when running an action script.
is there anyway to popup a query window in the GUI to ask the user for input?
JoBe
(417 rep)
Aug 9, 2020, 09:35 PM
• Last activity: Oct 26, 2020, 11:43 AM
4
votes
1
answers
1901
views
How can you get the current terminal line (the one that is still editable by the user)?
I need a way to use the current line which the users typed into as variable for a shell function. my current code, which can be called by ctrl+r zle -N search bindkey "^R" search search () { read str; fc -ln -30 | grep $(printf "%q\n" "$str"); } or simply, to call it as a function search () { fc -ln...
I need a way to use the current line which the users typed into as variable for a shell function.
my current code, which can be called by ctrl+r
zle -N search
bindkey "^R" search
search () {
read str;
fc -ln -30 | grep $(printf "%q\n" "$str");
}
or simply, to call it as a function
search () {
fc -ln -30 | grep $(printf "%q\n" "$1");
}
updated: target pseudo code, to call as a function called by ctrl+r that needs no further input prompt
zle -N search
bindkey "^R" search
search ()
echo ""; #for better formatting because ctrl+R is not enter so the BUFFER(current line) gets corrupted and looks messy and the current input is not correctly shown
fc -ln -30 | grep $(printf "%q\n" "$BUFFER"); #edited to be the solution where $BUFFER is the current terminal line
}
HopefullyHelpful
(161 rep)
Aug 26, 2014, 02:56 PM
• Last activity: Sep 26, 2020, 04:49 PM
1
votes
1
answers
1908
views
Why does read appear to fail silently in my script called from another script?
Let me paint a picture for your. You write some deployment scripts or build scripts or somethings etc. which run commands on the remote to do things like e.g. create users, install/update package etc. and thus you might be worried that maybe you forgot to add that `--gecos ''` to your `adduser` or d...
Let me paint a picture for your. You write some deployment scripts or build scripts or somethings etc. which run commands on the remote to do things like e.g. create users, install/update package etc. and thus you might be worried that maybe you forgot to add that
--gecos ''
to your adduser
or didn't provide that DEBIAN_FRONTEND=noninteractive
for all of your apts or something that you might not even be aware of. Now, such scripts tend to be non-interactive. You don't want to be prompted for anything and in case for some reason prompting happens, you would like the whole operation to fail. However, what I'm seeing with bash in such scenarios is that instead of failing and returning a non 0 error code (even if I set -e
), it does the worst possible thing. It interrupts and returns 0. This means the caller has no way of knowing that the script did not complete properly, but in fact was interrupted.
Here's a silly example to easily illustrate and toy with the problem. You can imagine bunch of stuff going on around this script. Maybe this bit code is actually executed using ssh on the remote, installing some packages instead of read line
etc. and after this block you expect that all the code ran successfully.
shell
set -e
# Do stuf...
/bin/bash <
Output
gonna try to be interactive
return value 0
I already noticed that if I use bin/sh
instead of bash I get a different behaviour. It does not automatically immediately stop execution on the read and return 0. In fact by default it will just move on and I need to explicitly set -e
to make it "short circuit" and with that it in fact does then give me return value 1. But is there any way to make this work sanely with bash?
Timo
(683 rep)
Sep 6, 2020, 10:55 AM
• Last activity: Sep 11, 2020, 09:41 PM
2
votes
2
answers
659
views
How can I modify input variables with string modifiers in zsh?
I've been working on a `bold` function as a proof-of-concept and a challenge to myself. I am trying to input text (e.g.`foo`) and have it print to standard output as it's bold counterpart (**`foo`**). Context: I've been using `echo` and basing it off of my `PROMPT` variable in my theme file. I am no...
I've been working on a
bold
function as a proof-of-concept and a challenge to myself. I am trying to input text (e.g.foo
) and have it print to standard output as it's bold counterpart (**foo
**).
Context:
I've been using echo
and basing it off of my PROMPT
variable in my theme file. I am not using any frameworks.
The theme uses codes like %B%n%b
to bold the username (%n
), but I don't know how to replace that %n
with user input ($1
). Any Help?
Edit: Attempted Code
echo '%B'"$1"'%b'
-tried with and without quotes in various locations, as well as with sub-shell ({}
)
user426441
(21 rep)
Aug 1, 2020, 09:42 PM
• Last activity: Aug 2, 2020, 08:21 AM
0
votes
1
answers
81
views
Printing all lines between two strings, with one as a user input, using sed
I'm trying to use: sed -n '/String1/,/String2/p' Filename to print all lines between String1 and String2. Although I want to add String1 as a user input so, read $userinput sed -n '/$userinput/,/String2/p' Filename. But as the input is within quotation is is read as the string `$userinput` instead o...
I'm trying to use:
sed -n '/String1/,/String2/p' Filename
to print all lines between String1 and String2. Although I want to add String1 as a user input so,
read $userinput
sed -n '/$userinput/,/String2/p' Filename.
But as the input is within quotation is is read as the string
$userinput
instead of the given input.
Richard
(1 rep)
Jul 7, 2020, 10:09 PM
• Last activity: Jul 7, 2020, 10:23 PM
-1
votes
1
answers
2703
views
How to create a shell script that would create a copy of a file (selected by the user) and copy it to a directory (selected by the user) in Bash?
How to solve this task? > To create a copy of a file. > > - The file should be in your current directory (the name of the file to be given by the user) > - The destination directory name to be given by the user. This is how far I've got: echo "Enter the name of the file:" read filename cp -r /home/$...
How to solve this task?
> To create a copy of a file.
>
> - The file should be in your current directory (the name of the file to be given by the user)
> - The destination directory name to be given by the user.
This is how far I've got:
echo "Enter the name of the file:"
read filename
cp -r /home/$FILE ;;
Just to add more info, this is what the full exercise is based on:
The script should offer a menu with the following options:
1. To create a backup copy of a script file.
> The name of the backup copy should have backup after the name of the script
and be date stamped e.g. work3Script_backup_10_11_2015.
> It should be saved to your home directory using the Environment Variable
for your home directory.
> The script should error check that the file exists and is a normal file. If
this is not the case then the script should allow the user to re-enter the
filename until a valid filename is entered
2. To create a date stamped log file called e.g. log_file_10_11_2015
containing
> A list of who is logged into the system
> The disk usage and
> Your currently running processes.
> The file should be saved to an existing directory called log_dir which
should
be situated off your home directory
3. To create a copy of a file.
> The file should be in your current directory (the name of the file to be
given by the user)
> The destination directory name to be given by the user.
> The script should error check that the file exists and is a normal file. If this is not the case then the script should allow the user to re-enter the filename until a valid filename is entered.
> The script should check that the destination directory exists. If this is
not the case then the script should allow the user to re-enter the
destination directory until a valid directory is entered.
Here is the menu I created:
#!/bin/bash
while true
do
echo "=============================="
echo "Menu"
echo "=============================="
echo "Option 1 Backing up files: "
echo "Option 2 Date stamped log file: "
echo "Option 3 Create a copy of a file: "
echo "Option 4 Moving a file to place giving by the user: "
echo "Enter q to quit the menu: "
echo -e "\n"
echo -e "Enter your option: \c"
read answer
case "$answer" in
1) while true ; do
echo "Enter the file name:"
read filename
if [ -f "$filename" ]; then
echo "The file exists."
break
else
echo "File doesn't exist."
fi
done
FILE=$(date +"outcome3_backup_%d_%m_%y.sh")
touch /home/robert/$FILE ;;
2)FILE=$(date +"log_file_%d_%m_%y.txt")
touch /home/robert/log_dir/$FILE
echo "Users online: " > /home/robert/log_dir/$FILE
(users) >> /home/robert/log_dir/$FILE
echo "Running proccesses:" >> /home/robert/log_dir/$FILE
ps -a >> /home/robert/log_dir/$FILE
echo "Available disk space:" >> /home/robert/log_dir/$FILE
df --total -h|head -n 1 >> /home/robert/log_dir/$FILE
df --total -h|tail -n 1 >> /home/robert/log_dir/$FILE ;;
3) ;;
q) exit ;;
esac
done
Angelism
(3 rep)
May 29, 2020, 10:54 PM
• Last activity: May 30, 2020, 11:06 AM
2
votes
1
answers
1406
views
Script that validates 3 inputs
This is what I have. I am trying to validate 3 inputs. The first and the second inputs do not ask me to enter the correct input. What is wrong? #!/bin/bash while : do echo "Please enter your tittle:" read TITTLE echo "Please enter your surname:" read SURNAME echo "Please enter your ID No." read ID i...
This is what I have. I am trying to validate 3 inputs. The first and the second inputs do not ask me to enter the correct input. What is wrong?
#!/bin/bash
while :
do
echo "Please enter your tittle:"
read TITTLE
echo "Please enter your surname:"
read SURNAME
echo "Please enter your ID No."
read ID
if [ "$TITTLE" = "" ] || [ "${TITTLE//[!0-9]}" != "" ];
then
echo "Enter your valid tittle without special characters."
echo "Please try again."
exit 1
fi
if [ "$SURNAME" = "" ] || [ "${SURNAME//[!0-9]}" != "" ];
then
echo "Enter your valid surname without special characters."
echo "Please try again."
exit 1
fi
if [ "$ID" = "" ] || [ "${ID//[0-9]}" != "" ];
then
echo "Enter your valid ID No. without special characters."
echo "Please try again"
else
echo "Thank you" $TITTLE $SURNAME
break
fi
done
Peter Thapelo Matlhasi
(27 rep)
Mar 10, 2020, 06:57 AM
• Last activity: Mar 10, 2020, 12:04 PM
Showing page 1 of 20 total questions