passwd in one command isn't working
/bin/passwd
may be opening /dev/tty
to force reading from a terminal instead of a pipe.
You may be better off encrypting (hashing, really) your new password using crypt()
, and then replacing the password hash in /etc/shadow
(for systems that have it) or /etc/passwd
(for systems that don't). This has the disadvantage of being somewhat OS-dependent, but it doesn't get into weird tty games.
You might also be able to force allocation of a tty in ssh - ssh can operate both with or without one. Then you would add a couple of delays before sending the password in plaintext twice - this method is less OS-dependent, but tty games can be less than fun sometimes.
Using the passwd command from within a shell script
from "man 1 passwd
":
--stdin
This option is used to indicate that passwd should read the new
password from standard input, which can be a pipe.
So in your case
adduser "$1"
echo "$2" | passwd "$1" --stdin
[Update] a few issues were brought up in the comments:
Your passwd
command may not have a --stdin
option: use the chpasswd
utility instead, as suggested by ashawley.
If you use a shell other than bash, "echo" might not be a builtin command,
and the shell will call /bin/echo
. This is insecure because the password
will show up in the process table and can be seen with tools like ps
.
In this case, you should use another scripting language. Here is an example in Perl:
#!/usr/bin/perl -w
open my $pipe, '|chpasswd' or die "can't open pipe: $!";
print {$pipe} "$username:$password";
close $pipe
Why isn't a semicolon in command substitution output treated identical to one in the original code?
Command substitution results (like expansion of variables) do not go through all parsing phases; they only go through word-splitting[1] and glob expansion[2], and even those happen only when the expansion itself is unquoted.
That means that your result is identical to:
cd "..;" "echo" "123"
...the semicolon is treated as literal text to be passed to the cd
command, not shell syntax.
This is a feature, not a bug: If command substitution results were parsed as syntax, writing secure shell scripts handling untrusted data would be basically impossible.
[1] dividing the results into "words" on characters in IFS
-- or, by default, whitespace.
[2] looking at whether each resulting word can be treated as a filename-matching pattern, and, if so, matching them against the local filesystem.
Related Topics
How to Run a Linux Executable from Any Directory in Terminal
Printing Floating Point Numbers in Assembler
Nohup Create New Files Nohup.Out by Day
Centos Cgconfig Fails to Start
Linux Intel 64Bit Assembly Division
Why Does Cat <<< $Var1 Lose Newlines
Linux Grep/Sed Certain Lines - Space Removal
How to Get Exact List of Collections Form Mongo Database in Shell Script
Format and Filter File to CSV Table
Grep in File and Replace String
How to Populate /Dev with a Custom Directory with Udev
How to Join Columns of Two Files in Unix System
Perf: Strange Relation Between Software Events
How to Make Sudo Save The Password
The Behavior When a Gnu Make Phony Target Happens to Be The Same as a Directory Name