Search code examples
bashshellsshcarriage-return

Bash ssh execute command occationally result in ^M


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.


Solution

  • 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.