Sending SMS from command line


Let's send an SMS using USB 3G modem and Linux command line.

(If you have USB modem you may need the usbmodeswitch package or something like it that can prepare the device to work as modem.)

Sending manully using minicom

First, install minicom — terminal for serial communication:

# apt-get install usb-modeswitch
# apt-get install minicom

Now configure minicom:

$ minicom -s

Go to Serial port setup and change device to one that works for your modem.

Now run minicom without arguments and try these commands:


The modem should send SMS "message" to the specificed number.

Sending using standard commands

You can do the same by using standard linux commands too:

# stty -F /dev/ttyUSB3 speed 9600 -brkint -icrnl ixoff -imaxbel -opost -onlcr -isig -icanon -echo -echoe
# tail -f /dev/ttyUSB3 &
# echo -e "AT+CMGF=1\r\n" > /dev/ttyUSB3
# echo -e "AT+CMGS=\"+123456789\"\r\n" > /dev/ttyUSB3
# echo -e "message\032\r\n" > /dev/ttyUSB3

What can easily be translated to sh-script.

Note the first line with stty command. All data between computer and 3G modem are transfered through USB, so it looks like it's not necessary to set the speed and other options, but it is. So just stty before your modem commands.


One problem here is that SMS can be sent in two modes: text and so called PDU (binary), and text SMSs are flash by default in my 3G modem at least and I couldn't figure out how to force these flash messages to be saved into flash phone memory...

Sending PDU SMS by script

So, here's a python script that send normal messages


import os
import sys
import time

def dectobin(i):
  b = ''
  while i > 0:
    j = i & 1
    b = str(j) + b
    i >>= 1
  return b

def SendSMS(dev,number,text):
  pdu_data = '00'
  pdu_data += '11' #SMS-SUBMIT
  pdu_data += '00' #TP-Message-Reference
  pdu_data += '0B' #Address-Length
  pdu_data += '91' #Address-Length
  '''Convert telephone number'''
  number += 'F'
  pdu_number = ''
  for i in range(0,len(number)):
    if i%2==0:
    pdu_number += number[i] + number[i-1]
  pdu_data += pdu_number
  pdu_data += '00' #TP-Protocol identifier
  pdu_data += '00' #TP-Data coding scheme
  pdu_data += 'AA' #TP-Validity-Period

  '''Convert text to binary format'''
  pdu_text_bin = []
  for i in text:
    if dec_s == 95:
      dec_s = 17
    if dec_s == 94:
      dec_s = 1
    if dec_s == 64:
      dec_s = 0
    if dec_s == 36:
      dec_s = 2
    if dec_s == 123:
      dec_s = 40
    if dec_s == 125:
      dec_s = 41
    if dec_s == 124:
      dec_s = 64
    if dec_s == 126:
      dec_s = 61
    if dec_s == 92:
      dec_s = 47
    if dec_s == 91:
      dec_s = 60
    if dec_s == 93:
      dec_s = 62
    bin = dectobin(dec_s)
    le = len(bin)
    while le<7:
      le = len(bin)

  '''Encode binary to PDU format'''
  pdu_text_bin_cp = []
  for i in range(0,len(text)):
    if (i>0) & ((i+1)%8==0):
    if n==8:
    if i==len(text)-1:
      cp = pdu_text_bin[i][0:8-n]
      cp = str(pdu_text_bin[i+1][7-n:7] + pdu_text_bin[i])[0:8]

  '''Convert PDU to hex'''
  for i in pdu_text_bin_cp:
    hexi = str(hex(int(i,2)))[2:4].upper()
    if len(hexi) == 1:
      hexi = '0' + str(hexi)
    pdu_text += hexi

  '''Calculate text length'''
  len_hex = hex(len(text))[2:4].upper()
  if len(len_hex) == 1:
    len_hex = '0' + str(len_hex)

  '''Calculate PDU length'''
  pdu_len = str(len(pdu_data)/2-1)

  if True:
    fd =, os.O_RDWR)
    '''os.write(fd, "AT+CMGF=0 \015")'''
    os.write(fd, "ATZ\r\n")
    os.write(fd, "AT+CMGF=0\r\n")
    os.write(fd, "AT+CMGS=" + pdu_len + "\r\n")
    os.write(fd, pdu_data + "\032\r\n")

def main(argv):
  return 0

if __name__ == '__main__': main(sys.argv)

Honestly i cant remember where i've found this crap, but it works.] It translates the message and its options into binary PDU structure and sends it to the modem with usual input/output commands (so it needs stty too).


Good luck with smsing with your programs]



free hit counters