How to get whole command line from a process?

You could use the -o switch to specify your output format:

$ ps -eo args

From the man page:

Command with all its arguments as a string. Modifications to the arguments may be shown. [...]

You may also use the -p switch to select a specific PID:

$ ps -p [PID] -o args

pidof may also be used to switch from process name to PID, hence allowing the use of -p with a name:

$ ps -p $(pidof dhcpcd) -o args

Of course, you may also use grep for this (in which case, you must add the -e switch):

$ ps -eo args | grep dhcpcd | head -n -1

GNU ps will also allow you to remove the headers (of course, this is unnecessary when using grep):

$ ps -p $(pidof dhcpcd) -o args --no-headers

On other systems, you may pipe to AWK or sed:

$ ps -p $(pidof dhcpcd) -o args | awk 'NR > 1'
$ ps -p $(pidof dhcpcd) -o args | sed 1d

Edit: if you want to catch this line into a variable, just use $(...) as usual:

$ CMDLINE=$(ps -p $(pidof dhcpcd) -o args --no-headers)

or, with grep :

$ CMDLINE=$(ps -eo args | grep dhcpcd | head -n -1)

Method #1 - Using ps

You could use ps -eaf | grep 1234.

Example

$ ps -eaf | grep 28865
saml     28865  9661  0 03:06 pts/2    00:00:00 bash -c sleep 10000; while [ 1 ];do echo hi;sleep 10;done
saml     28866 28865  0 03:06 pts/2    00:00:00 sleep 10000

NOTE: Busybox's ps doesn't include the -eaf switches as shown above from a typical ps that's included with most Linuxes, however Busybox's ps shows what looks to be very similar output to the example I provided. You can install Busybox on most Linuxes and run it like so:

$ busybox ps
  852 root       0:00 /sbin/auditd -n
  855 root       0:01 /sbin/audispd
  857 root       0:00 /usr/sbin/sedispatch
  866 root       0:00 /usr/sbin/alsactl -s -n 19 -c -E ALSA_CONFIG_PATH=/etc/alsa/alsactl.conf --initfile=/lib/alsa/init/00main rdaemon
  867 root       0:00 /usr/libexec/bluetooth/bluetoothd
  869 root       0:01 {firewalld} /usr/bin/python -Es /usr/sbin/firewalld --nofork --nopid
  871 root       0:32 /usr/libexec/accounts-daemon
  873 rtkit      0:05 /usr/libexec/rtkit-daemon
  875 root       0:00 /usr/sbin/ModemManager
  876 avahi      0:03 avahi-daemon: running [dufresne.local]
  878 root       0:54 /usr/sbin/irqbalance --foreground
  884 root       0:00 /usr/sbin/smartd -n -q never
  886 avahi      0:00 avahi-daemon: chroot helper
  891 chrony     0:01 /usr/sbin/chronyd
  892 root       0:01 /usr/lib/systemd/systemd-logind
  893 dbus       1:28 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation

Method #2 - Using /proc

You can also look at the cmdline file that each PID has under /proc/<pid>.

$ cat /proc/28865/cmdline 
bash-csleep 10000; while [ 1 ];do echo hi;sleep 10;done

But notice that it's missing the spacing. This is due to a NUL character being used within this file to separate your command line arguments. Not to worry though, these can be stripped out.

$ tr '\0' ' ' </proc/28865/cmdline
bash -c sleep 10000; while [ 1 ];do echo hi;sleep 10;done

References

  • How can I see the exact command line being executed inside some bash instance?

Try something like this:

(example output from busybox on OpenWrt on one of my routers)

root@ap8:~# xargs -0 printf '%s\n' </proc/991/cmdline
/usr/sbin/uhttpd
-f
-h
/www
-r
ap8
-x
/cgi-bin
-u
/ubus
-t
60
-T
30
-k
20
-A
1
-n
3
-N
100
-R
-p
0.0.0.0:80
-p
[::]:80

/proc/$PID/cmdline contains the arguments of process $PID like a C-ish strings one after another. Each string is zero terminated.

Quotes arround some arguments or options are shell stuff. You have to look closer at the lines being shown and where spaces or other characters with special meaning for the shell are used. You will need to quote that character(s) somehow or the complete argument when joining these lines to a command line again.