3

Here is my command with IP's commented out with semanticIP's

ssh -p 2022 -L 9389:localRDPIP:3389 user@publicIP \
su -c "export HISTCONTROL=ignorespace; \
iptables -t nat -A PREROUTING -p tcp --dport 3389 -j DNAT --to-destination localRDP_IP:3389; \
iptables -t nat -A POSTROUTING -p tcp -d localRDP_IP --dport 3389 -j SNAT --to-source jumpIP";

basically, I'm trying to run some remote routing, which is not the question. The question is how do I run such a command?

The best test I've been able to do is:

ssh -p 2022 -L 9389:localRDPIP:3389 user@publicIP -t "su -c nano; nano"

but I don't know how to do the spaces. If I have spaces in my commands in the -c "quoted area" other than a single command, I get an error.

Note: I realize that with ssh port forwarding, iptables commands may be unnecessary.

0
1

psql (and by extension mysql) had a similar limitation. While reading documentation on psql, I came across this

-c command --command=command Specifies that psql is to execute one command string, command, and then exit. This is useful in shell scripts. Start-up files (psqlrc and ~/.psqlrc) are ignored with this option.

command must be either a command string that is completely parsable by the server (i.e., it contains no psql-specific features), or a single backslash command. Thus you cannot mix SQL and psql meta-commands with this option. To achieve that, you could pipe the string into psql, for example: echo '\x \ SELECT * FROM foo;' | psql. (\ is the separator meta-command.)

If the command string contains multiple SQL commands, they are processed in a single transaction, unless there are explicit BEGIN/COMMIT commands included in the string to divide it into multiple transactions. This is different from the behavior when the same string is fed to psql's standard input. Also, only the result of the last SQL command is returned.

Because of these legacy behaviors, putting more than one command in the -c string often has unexpected results. It's better to feed multiple commands to psql's standard input, either using echo as illustrated above, or via a shell here-document, for example:

psql <<EOF
\x
SELECT * FROM foo;
EOF

for my case, I merely modified my echo statement

echo drop database if exists somedb; create database somedb;drop table if exists ur_table; CREATE TABLE ur_table (timestamp date, open real, high real,low real,close real,adjusted_close real,volume real,dividend_amount real,split_coefficient real,CONSTRAINT timestamp_pkey PRIMARY KEY (timestamp)); COPY ur_table(timestamp,open,high,low,close,adjusted_close,volume,dividend_amount,split_coefficient) FROM 'c:\test\temp.csv' DELIMITER ',' CSV HEADER;| psql -U postgres
1

As shown in the man page for su (man su) the -c option takes a single shell command, passed to your current shell for execution by its -c command:

-c, --command COMMAND Specify a command that will be invoked by the shell using its -c.

COMMAND must be a single argument, but there's nothing in more modern versions of su stopping you quoting multiple commands for execution by the shell that su calls:

ssh -p 2022 -L 9389:localRDPIP:3389 user@publicIP su -c '
    export HISTCONTROL=ignorespace;
    iptables -t nat -A PREROUTING -p tcp --dport 3389 -j DNAT --to-destination localRDP_IP:3389;
    iptables -t nat -A POSTROUTING -p tcp -d localRDP_IP --dport 3389 -j SNAT --to-source jumpIP
'

I'm not entirely sure what you want to achieve with your second command, though. At the moment it's set up to run nano as the root user, and then to run it again as your own account. Is this what you wanted? Or did you want to run nano twice as the root user, like this:

ssh -p 2022 -L 9389:localRDPIP:3389 user@publicIP -t su -c 'nano; nano'
3
  • The second was supplied as an example of what I could accomplish w multiple commands (no options). Your bash example might be the answer I was looking for! Thank you! Oct 9 '17 at 1:41
  • So, does ssh -p 2022 -L 9389:localRDPIP:3389 user@publicIP -t su -c bash -c 'nano; nano' work for you? Because the unquoted bash -c 'nano;nano' doesn't for me. it just replaces su's -c with a different -c that you meant to pass to bash. And if I want to provide a user to su it also gets weird because it's unquoting the nano and taking that as the user instead.
    – dlamblin
    Aug 15 '20 at 5:37
  • @dlamblin that's interesting. Looks the way su handles the arguments has changed. I'll update my question for the more modern version. Thank you
    – roaima
    Aug 15 '20 at 11:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.