Separate an email address into its username and domain name
The general style looks good. The biggest opportunity for improvement is your use of getopt. You should use the newer and easier argparse instead. Most of your code is used to parse and use the command line arguments. All of that can be done in three lines with argparse.
import argparse

arg_parser = argparse.ArgumentParser()
arg_parser.add_argument(&quot;-f&quot;, &quot;--file&quot;, dest=&quot;file&quot;, default=False, action=&quot;store_true&quot;)
arg_parser.add_argument(&quot;input&quot;, type=str)
args = arg_parser.parse_args()

Instead of using --single or --list, I added a single flag --file (or -f), as the former choice is not only ambiguous (what happens if you specify neither or both?) as well as potentially misleading in their name.
A help option with &quot;-h&quot; is introduced automatically.
&quot;-f&quot;, &quot;--file&quot; are the flags you can use to specify this argument. dest=file means that the created object args wil have an attribute args.file that stores the resulting value. action=&quot;store_true&quot; means that the flag has to be specified without a value (i.e. -f instead of -f True) to set it.
After that, you can access your inputs as a strings (because type=str) by args.input (because the first argument to add_argument was &quot;input&quot;).
open of a file should always be paired with a close when you are done using it, as is also true for other I/O objects such as network connections. Instead of manually calling close, one should prefer to use Python's context managers with the with keyword, which automatically perform any cleanup.
if args.file:
    with open(args.input, &quot;r&quot;) as file:
        emails = file.readlines()
else:
    emails = [args.input]

Your code to split the email into username and domain can be done with str.split, assuming that there is exactly one &quot;@&quot;. If there are not &quot;@&quot; or more than one, you should probably notify the user that there is an error anyway. If you want to have actual &quot;serious&quot; code that goes into production in a live system, see Toby Speight's comment on pointers how to properly do that.
    if email.count(&quot;@&quot;) != 1:
        ...  # Notify the user
    username, domain = email.split(&quot;@&quot;)
    print(f&quot;Your username: {username}&quot;)
    print(f&quot;Your domain name: {domain}&quot;)

Finally, your use of sys.exit is incorrect. You should only use sys.exit(n) with an integer n. sys.exit(0) means &quot;successful&quot;, anything else means &quot;failed&quot;. Unless you have specific needs, sys.exit(1) is the default choice for failure.
To give user friendly error messages, the easiest way is to use print. You can show the messages as an error by specifying file=sys.stderr (as opposed to the default file=sys.stdout).
        print(f&quot;{email} is not a valid email.&quot;, file=sys.stderr)
        sys.exit(1)

In total, this is what I'd propose your program could look like:
import sys
import argparse

arg_parser = argparse.ArgumentParser()
arg_parser.add_argument(&quot;-f&quot;, &quot;--file&quot;, dest=&quot;file&quot;, default=False, action=&quot;store_true&quot;)
arg_parser.add_argument(&quot;input&quot;, type=str)
args = arg_parser.parse_args()

if args.file:
    with open(args.input, &quot;r&quot;) as file:
        emails = file.readlines()
else:
    emails = [args.input]

for email in emails:
    if email.count(&quot;@&quot;) != 1:
        print(f&quot;{email} is not a valid email.&quot;, file=sys.stderr)
        sys.exit(1)
    username, domain = email.split(&quot;@&quot;)
    print(f&quot;Your username: {username}&quot;)
    print(f&quot;Your domain name: {domain}&quot;)