I have to write a useradd script which adds a new user and sets for him a home directory.
#!/bin/bash
echo "Name:"
read name
echo "Password:"
read password
echo "Group:"
read group
useradd -m -G $group -s /bin/bash -p $password $name
Everything works as intended but I have problems with the password in the following line -
useradd -m -G $group -s /bin/bash -p $password $name
It does not work so I need to use later in terminal passwd command.
How can I rebuild my script so I won't need to use passwd to setup password correctly? I have read that you can use stdin but I was not able to do this correctly.
If you prefer to pipe the user's password from STDIN, use chpasswd utility which is quick and simple.
as suggested by #Ardit.
This script should work for your purpose, assuming you meet the following conditions-
You are interacting as the root user
You have an existing group created for the purpose of your new user
#!/bin/bash
echo "Name:"
read name
echo "Password:"
read password
echo "Group:" # group must exist
read group
# add new user, set group, create new home directory
useradd -G $group -m $name
# update new user password by piping from STDIN
echo ""$name":"$password"" | chpasswd
# change the default user shell to bash
chsh -s /bin/bash $name
First we execute useradd command to create the new user and assign it to an existing group.
Then we pipe the name and password into chpasswd. If you're wondering why wrap those variable expansions with double quotes, check this answer out .
Finally chsh utility is used to update the user shell.
Why not execute everything in a single statement?
I prefer subdividing a problem into smaller tasks for easier understanding.
Related
I am new to bash scripting. I wrote a script that can create groups and users which works just fine, but my challenge now is how do I make the script create an ssh key pair for a particular user. From my script, it stopped working immediately after you switch to that user and it doesn't proceed to create the ssh key pair.
Below is my script.
for group in admin support engineering
do
sudo groupadd $group
sudo useradd -m -s /bin/bash achebeh_${group}
done
sudo passwd achebeh_admin
sudo su achebeh_admin
ssh-keygen -t rsa
So please how can I go about creating an ssh pair for the achebeh_admin user using this script. I am open to learn. Please this is my firs script after following a tutorial course.
#Achebe-peter If I got your requirements correctly from your short description, this will do the job for you.
Note:
Try this script in a test environment at your own risk!
This script best performs assuming that you don't have configured users and related files
#!/bin/bash
### Configuration Parameters Start ###
## The username that doesn't exist and you want to create.
user_name_prefix='testuser'
## The groups array that doesn't exist and you want to create and assign them to your user.
groups=(testadmin testsupport testengineering)
## SSH-key lenght
ssh_key_lenght='2048'
### Configuration Parameters End ###
for group in ${groups[#]} ;do
# Set username containing the prefix and group name
user="${user_name_prefix}_${group}"
# create such user if not exist
getent passwd ${user} &>/dev/null
if [ "$?" -ne 0 ] ;then
sudo useradd -m -s /bin/bash "${user}"
echo -e "\nType password for: ${user}"
sudo passwd ${user}
fi
# Create '.ssh' directory in user's home directory
if ! [ -d /home/${user}/.ssh ] ;then
sudo mkdir /home/${user}/.ssh
fi
# Generate ssh-key pair and move them to correspondig user's '.ssh/' dir.
ssh_file_name="./${user}_ssh"
(
echo "${ssh_file_name}"
echo ""
echo ""
) | ssh-keygen -t rsa -b ${ssh_key_lenght}
sudo mv -i "${ssh_file_name}" "${ssh_file_name}.pub" /home/${user}/.ssh/
sudo chown ${user}:${user} /home/${user}
# Create the groups (if does not exist)
getent group ${group} &>/dev/null
if [ "$?" -ne 0 ] ;then
sudo groupadd ${group}
fi
# Assign relevant group to the new user
sudo usermod -aG ${group} ${user}
done
exit 0
Tested in
GNU bash, version 5.0.17(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
PS. Please vote up my answer and mark it as the correct answer if it satisfies your requirements.
I've written a script that takes, as an argument, a string that is a concatenation of a username and a project. The script is supposed to switch (su) to the username, cd to a specific directory based upon the project string.
I basically want to do:
su $USERNAME;
cd /home/$USERNAME/$PROJECT;
svn update;
The problem is that once I do an su... it just waits there. Which makes sense since the flow of execution has passed to switching to the user. Once I exit, then the rest of the things execute but it doesn't work as desired.
I prepended su to the svn command but the command failed (i.e. it didn't update svn in the directory desired).
How do I write a script that allows the user to switch user and invoke svn (among other things)?
Much simpler: use sudo to run a shell and use a heredoc to feed it commands.
#!/usr/bin/env bash
whoami
sudo -i -u someuser bash << EOF
echo "In"
whoami
EOF
echo "Out"
whoami
(answer originally on SuperUser)
The trick is to use "sudo" command instead of "su"
You may need to add this
username1 ALL=(username2) NOPASSWD: /path/to/svn
to your /etc/sudoers file
and change your script to:
sudo -u username2 -H sh -c "cd /home/$USERNAME/$PROJECT; svn update"
Where username2 is the user you want to run the SVN command as and username1 is the user running the script.
If you need multiple users to run this script, use a %groupname instead of the username1
You need to execute all the different-user commands as their own script. If it's just one, or a few commands, then inline should work. If it's lots of commands then it's probably best to move them to their own file.
su -c "cd /home/$USERNAME/$PROJECT ; svn update" -m "$USERNAME"
Here is yet another approach, which was more convenient in my case (I just wanted to drop root privileges and do the rest of my script from restricted user): you can make the script restart itself from the correct user. This approach is more readable than using sudo or su -c with a "nested script". Let's suppose it is started as root initially. Then the code will look like this:
#!/bin/bash
if [ $UID -eq 0 ]; then
user=$1
dir=$2
shift 2 # if you need some other parameters
cd "$dir"
exec su "$user" "$0" -- "$#"
# nothing will be executed beyond that line,
# because exec replaces running process with the new one
fi
echo "This will be run from user $UID"
...
Use a script like the following to execute the rest or part of the script under another user:
#!/bin/sh
id
exec sudo -u transmission /bin/sh - << eof
id
eof
Use sudo instead
EDIT: As Douglas pointed out, you can not use cd in sudo since it is not an external command. You have to run the commands in a subshell to make the cd work.
sudo -u $USERNAME -H sh -c "cd ~/$PROJECT; svn update"
sudo -u $USERNAME -H cd ~/$PROJECT
sudo -u $USERNAME svn update
You may be asked to input that user's password, but only once.
It's not possible to change user within a shell script. Workarounds using sudo described in other answers are probably your best bet.
If you're mad enough to run perl scripts as root, you can do this with the $< $( $> $) variables which hold real/effective uid/gid, e.g.:
#!/usr/bin/perl -w
$user = shift;
if (!$<) {
$> = getpwnam $user;
$) = getgrnam $user;
} else {
die 'must be root to change uid';
}
system('whoami');
This worked for me
I split out my "provisioning" from my "startup".
# Configure everything else ready to run
config.vm.provision :shell, path: "provision.sh"
config.vm.provision :shell, path: "start_env.sh", run: "always"
then in my start_env.sh
#!/usr/bin/env bash
echo "Starting Server Env"
#java -jar /usr/lib/node_modules/selenium-server-standalone-jar/jar/selenium-server-standalone-2.40.0.jar &
#(cd /vagrant_projects/myproj && sudo -u vagrant -H sh -c "nohup npm install 0<&- &>/dev/null &;bower install 0<&- &>/dev/null &")
cd /vagrant_projects/myproj
nohup grunt connect:server:keepalive 0<&- &>/dev/null &
nohup apimocker -c /vagrant_projects/myproj/mock_api_data/config.json 0<&- &>/dev/null &
Inspired by the idea from #MarSoft but I changed the lines like the following:
USERNAME='desireduser'
COMMAND=$0
COMMANDARGS="$(printf " %q" "${#}")"
if [ $(whoami) != "$USERNAME" ]; then
exec sudo -E su $USERNAME -c "/usr/bin/bash -l $COMMAND $COMMANDARGS"
exit
fi
I have used sudo to allow a password less execution of the script. If you want to enter a password for the user, remove the sudo. If you do not need the environment variables, remove -E from sudo.
The /usr/bin/bash -l ensures, that the profile.d scripts are executed for an initialized environment.
I'm looking to respond to a password prompt in the linux terminal. I know how to do this with echo and a non-password prompt. For example, let's say whatsyourname.sh prompted me for a string with my name after being ran, but didn't allow my name to be passed as an argument in the inital command. I would do the following:
echo -e "dan" | ./whatsyourname.sh
However, if I ran a command that asked me for a password after being ran, the following does not work:
echo -e "supersecurepassword" | sudo apt-get update
I'm guessing this has something to do with the fact that the characters are hidden while a password is being input in the command line. How would I respond to a password prompt within the inital command?
You're looking for sudo -S
Explaining -S - man sudo
-S, --stdin
Write the prompt to the standard error and read the password from the standard input instead of
using the terminal device. The password must be followed by a newline character.
Simple,
#!/bin/bash
echo "notsecure" | sudo -S apt-get update
Variable,
#!/bin/bash
pass="notsecure"
echo $pass | sudo -S apt-get update
Lets still type it,
#!/bin/bash
read -s -p "[sudo] sudo password for $(whoami): " pass
echo $pass | sudo -S apt-get update
Explaining -s and -p - help read
-r do not allow backslashes to escape any characters
-s do not echo input coming from a terminal
Handy if you make a script that logs into multiple servers to view route -n for example.
I am having some trouble with creating a new linux user using a script which should be basic, but its doing my head in as i am trying to figure out how it works
This is the code
clear
cd home
echo "Enter Username"
read username
echo "Enter Password"
read password
useradd -m $username
usermod -a -G myGroup $username
grep myGroup /etc/group
I fixed the issue with the username, but I don't know how to store the password to the username
I am in root when this script is executed
All input appreciated!
Try:
clear
cd home
echo "Enter Username"
read username
echo $username
useradd -m $username
usermod -a -G myGroup $username
passwd $username
grep myGroup /etc/group
Note: I don't think that adding users in this way is recommended practice and I am assuming that you are sudo'ing this script.
This should get you close to what you are after
I more succinct answer if you don't like the one above:
clear
echo "Enter Username"
read username
adduser --gecos "" --ingroup myGroup $username
So I would like to make a script that create users from users.txt running
useradd -m -s /bin/false users_in_the_users.txt
and fill the password from passwords.txt twice (to confirm the passwords)
This is the script
#!/bin/bash
# Assign file descriptors to users and passwords files
exec 3< users.txt
exec 4< passwords.txt
exec 5< passwords.txt
# Read user and password
while read iuser <&3 && read ipasswd <&4 ; do
# Just print this for debugging
printf "\tCreating user: %s with password: %s\n" $iuser $ipasswd
# Create the user with adduser (you can add whichever option you like)
useradd -m -s /bin/false $iuser
# Assign the password to the user, passwd must read it from stdin
passwd $iuser
done
The problem is, it does not fill the passwords. And 1 more thing, I want the script to fill the passwords twice.
Any suggestions?
You have to supply the password on stdin. Replace:
passwd $iuser
with:
passwd "$iuser" <<<"$ipasswd
$ipasswd"
or, as suggested by mklement0:
passwd "$iuser" <<<"$ipasswd"$'\n'"$ipasswd"
The incantation <<< creates a here-string. The string that follows the <<< is provided as standard in to the command which precedes the <<<. In this case we provide the two copies of the password that the passwd command wants.
(The script reads these passwords from a plain text file. I will assume that your situation is some special case for which this is not as dangerous as it normally would be.)
John1024's answer is the correct one - his warning about reading passwords from plain-text files bears repeating.
Let me show the solution in context, without the file-descriptor acrobatics (exec 3<, ...):
#!/bin/bash
# NOTE: Be sure to run this script with `sudo`.
# Read user and password
while read iuser ipasswd; do
# Just print this for debugging.
printf "\tCreating user: %s with password: %s\n" $iuser $ipasswd
# Create the user with adduser (you can add whichever option you like).
useradd -m -s /bin/false $iuser
# Assign the password to the user.
# Password is passed via stdin, *twice* (for confirmation).
passwd $iuser <<< "$ipasswd"$'\n'"$ipasswd"
done < <(paste users.txt passwords.txt)
paste users.txt passwords.txt reads corresponding lines from the two files and puts them on a single line, separated with \t.
The result is piped to stdin via a process substitution (<(...)).
This allows read to read from a single source.
$\n is an ANSI C-quoted string that produces a (literal) newline.
#! /bin/bash
for i in {1..100}
do
`sudo mkdir -p /root/Desktop/userm$i`
`sudo useradd -m -d /root/Desktop/userm$i -s /bin/bash userm$i`
echo "userm$i:userm$i" | chpasswd
done
this will create 100 users. user name will be (userm1-userm100). home directory will be /root/Desktop/(userm1-user100)
password will be (userm1-userm100)
Instead of using this line:
useradd -m -s /bin/false $iuser
Try this one:
useradd -m -s /bin/false -p $ipasswd $iuser
You don't actually need this:
passwd $iuser <<< "$ipasswd"$'\n'"$ipasswd"
Kindly run the below script.
#!/bin/bash
#purpose: bash script to create multiple users with pre-defined passwords at once.
#Read_Me: The import file should be in two columns, first users name and second passwords.
#author: Bablish Jaiswal
#contact: linux.cnf#gmail.com
read -p "Kindly import/type Users Name-password file with location:- " creation_info
cat $creation_info |while read i p
do
( useradd $i && echo -e "${p}\n${p}" | passwd $i ) > /dev/null 2>&1 && echo $user ${i} created and password is ${p} || echo ${i} failed
done