I was conducting an experiment using bash script, and need to execute some commands on the remote SSH side[Both local and remote machines are Linux-based ]
When I use the following command [use localhost as SSH target here just as an experiment], the rx_tmp.log file will have a "^M" at the end of every line.
ssh -t user@localhost "echo 123123 | sudo -S bash -c \"export TERM=dumb && cd /home/user/redis_research/ && make clean && make\" " &> rx_tmp.log
[sudo] password for user: rm -f *.o dpdk-rx^M
g++ -c -O3 -include rte_config.h -march=native -I/usr/local/include -I/usr/include/libnl3 main.cpp -std=c++11 -o main.o^M
In file included from main.cpp:21:^M
main.h:16:13: warning: "ETH_MQ_RX_RSS" is deprecated^M
16 | .mq_mode = ETH_MQ_RX_RSS,^M
| ^~~~~~~~~~~~~~~~~~~~~ ^M
main.h:20:13: warning: "ETH_MQ_TX_NONE" is deprecated^M
20 | .mq_mode = ETH_MQ_TX_NONE^M
| ^~~~~~~~~~~~~~~~~~~~~ ^M
main.h:25:13: warning: "ETH_RSS_IP" is deprecated^M
25 | .rss_hf = ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP,^M
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^M
main.h:25:13: warning: "ETH_RSS_UDP" is deprecated^M
25 | .rss_hf = ETH_RSS_IP | ETH_RSS_UDP | ETH_RSS_TCP,^M
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^M
main.h:25:13: warning: "ETH_RSS_TCP" is deprecated^M
In file included from main.cpp:21:^M
main.h:456:20: warning: invalid suffix on literal; C++11 requires a space between literal and string macro [-Wliteral-suffix]^M
456 | "requested:%#"PRIx64" configured:%#"PRIx64"\n",^M
| ^^M
main.h:456:40: warning: invalid suffix on literal; C++11 requires a space between literal and string macro [-Wliteral-suffix]^M
456 | "requested:%#"PRIx64" configured:%#"PRIx64"\n",^M
| ^^M
main.cpp:308:32: warning: invalid suffix on literal; C++11 requires a space between literal and string macro [-Wliteral-suffix]^M
308 | rte_exit(EXIT_FAILURE, "Cannot init port %"PRIu16 "\n", port_id);^M
| ^^M
g++ -O3 -include rte_config.h -march=native -I/usr/local/include -I/usr/include/libnl3 main.o -o dpdk-rx -L/usr/local/lib/x86_64-linux-gnu -Wl,--as-needed -lrte_node -lrte_graph -lrte_flow_classify -lrte_pipeline -lrte_table -lrte_pdump -lrte_port -lrte_fib -lrte_ipsec -lrte_vhost -lrte_stack -lrte_security -lrte_sched -lrte_reorder -lrte_rib -lrte_dmadev -lrte_regexdev -lrte_rawdev -lrte_power -lrte_pcapng -lrte_member -lrte_lpm -lrte_latencystats -lrte_kni -lrte_jobstats -lrte_ip_frag -lrte_gso -lrte_gro -lrte_gpudev -lrte_eventdev -lrte_efd -lrte_distributor -lrte_cryptodev -lrte_compressdev -lrte_cfgfile -lrte_bpf -lrte_bitratestats -lrte_bbdev -lrte_acl -lrte_timer -lrte_hash -lrte_metrics -lrte_cmdline -lrte_pci -lrte_ethdev -lrte_meter -lrte_net -lrte_mbuf -lrte_mempool -lrte_rcu -lrte_ring -lrte_eal -lrte_telemetry -lrte_kvargs -lbsd -lisal_crypto -lcrypto^M
However, if I use the following two commands instead, the "^M" will be gone:
bash -c "echo 123123 | sudo -S bash -c \"export TERM=dumb && cd /home/user/redis_research/ && make clean && make\" " &> rx_tmp.log
ssh -t user@localhost "sudo -S bash -c \"export TERM=dumb && cd /home/user/redis_research/ && make clean && make\" " &> rx_tmp.log
Well, I can't use the first alternative because in reality, I do have to use SSH to run commands remotely, instead of locally. I don't want to use the second alternative because it requires me to type the password manually.
I wonder what went wrong.
Remove the -t
option from ssh
if you don't actually need to allocate a pseudo-tty. Since the remote side believes it's connected to a real tty, it is sending additional control characters (the ^M
aka a carriage return) that would normally help with terminal display, but since you're dumping the output into a file you are just capturing those characters literally.